什么是分词?为什么它在Shell编程中很重要?

阿梅里奥·巴斯克斯·雷纳(Amelio Vazquez-Reina)

我对分词在中扮演的角色感到困惑zsh在使用C,Python或MATLAB进行编程时,我还没有接触过这个概念,这引起了我的兴趣,即为什么分词似乎是Shell编程特有的。

之前,我已经在该站点和其他站点上阅读过分词的知识,但没有找到关于此概念的清晰解释。Wikipedia定义了单词拆分,但是似乎没有引用它如何应用于Unix shell的信息。

这是我对以下方面感到困惑的示例zsh

Z Shell FAQ中,我阅读以下内容:

3.1:为什么在$var哪里var="foo bar"不做我期望的事情?

在大多数Bourne-shell派生词中,诸如多词变量var="foo bar"在传递给命令或在for foo in $var循环中使用时都会分解为多个词默认情况下,zsh没有这种行为:该变量保持不变。(这不是错误!请参阅下文。)SH_WORD_SPLIT存在此选项是为了提供兼容性。

但是,在《 Z Shell手册》中,我读到以下内容:

SH_WORD_SPLIT (-y) <K> <S>

使字段拆分在未引用的参数扩展上执行。请注意,此选项与分词无关(请参阅参数扩展。)

为什么会说SH_WORD_SPLIT没有做与分词?单词拆分难道不是一本正经吗?

吉勒斯“别再邪恶了”

早期的shell只有一种数据类型:字符串。但是操作字符串列表是很常见的,通常是在将多个文件名作为参数传递给程序时。拆分的另一个常见用例是命令输出结果列表:命令的输出是字符串,但是所需的数据是字符串列表。要将文件名列表存储在变量中,请在文件名之间放置空格。然后像这样的shell脚本

files="foo bar qux"
myprogram $files

所谓myprogram三个参数,作为外壳分割字符串$files成单词。当时,文件名中的空格要么被禁止,要么被广泛认为是“未完成”。

Korn shell中引入了阵列:你可以字符串列表存储在一个变量。Korn外壳程序与当时建立的Bourne外壳程序保持兼容,因此裸变量扩展一直在进行字分割,并且使用数组需要一些语法开销。您将在上面编写代码段

files=(foo bar qux)
myprogram "${files[@]}"

Zsh从一开始就有数组,它的作者选择了一种较精巧的语言设计,但以向后兼容为代价。在zsh中(根据默认的扩展规则)$var不执行分词;如果要在变量中存储单词列表,则应使用数组;如果您真的想要分词,可以编写$=var

files=(foo bar qux)
myprogram $files

如今,文件名中的空格是您需要解决的,这是因为许多用户希望它们起作用,并且因为许多脚本是在安全敏感的上下文中执行的,攻击者可能会控制文件名。因此自动分词通常很麻烦。因此,我的一般建议是始终使用双引号,即write "$foo",除非您了解为什么在特定用例中需要分词。(请注意,裸变量扩展也将发生遍历。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章