2

我是 Bash 的新手,我看到 Bash 会自动进行分词:

a="1  2     3 4"

如果我 echo "a" by echo $aI got 1 2 3 4,它隐式地进行了分词。如果我遍历“a”,我分别得到 1、2、3 和 4。

我也从这里读到

shell 会扫描双引号内未出现的参数扩展、命令替换和算术扩展的结果以进行分词。

而且我还发现,如果我有

b=$a;
echo "$b"

我会得到

"1 2 3 4"

所以,这是我的问题:分词什么时候完成?它会改变字符串本身吗?echo是不是只有在我使用or for(循环)的时候才生效?

更一般地说,bash 如何处理它?

4

3 回答 3

4

实际上有几轮分词。第一个是在解析命令行之前执行的,所以echo $a被分成两个词echo$a。(这就是为什么类似a="echo foo | wc -l"; $a不执行管道的原因;在$a扩展之前解析完成)。该轮分词结束后,发生参数扩展,生成 2 个字符串,echo并且1 2 3 4. 参数扩展产生的字符串然后会进行分词,因为它没有被引用,产生 4 个额外的词1234

在 for 循环中,列表中的项目会被分词:

for b in $a; do

被扩展(在分词产生for, b, in, $a, ;, and之后do)到for, b, in, 1 2 3 4, ;, and do. 由参数扩展产生的字符串再次经历分词为1234

于 2013-08-28T21:25:51.283 回答
4

Bash 作为下一个工作 - 在解析脚本或命令行时:

  1. 解析和词法分析
  2. 扩张
    1. 大括号展开
    2. 标题扩展
    3. 变量扩展
    4. 算术和其他替代
    5. 命令替换
    6. 分词
    7. 文件名生成(通配符)
  3. 删除引号

正如你所看到的,分词几乎在最后,所以在例如算术扩展之后但在文件名通配之前,删除引号是最后一步。

于 2013-08-28T21:32:33.263 回答
2

阅读man bash。对于分配,它说

所有值都经过波浪号扩展、参数和变量扩展、命令替换、算术扩展和引号删除 [ ... ] 不执行分词,“$@”除外,如下面的特殊参数中所述。不执行路径名扩展。

在以下条件下也不会发生分词[[ ]]

[[ 和 ]] 之间的单词不进行分词和路径名扩展

于 2013-08-28T21:14:58.447 回答