shell 扩展的顺序:命令替换与算术扩展

shell 扩展的顺序:命令替换与算术扩展

考虑在 bash 命令行中输入以下代码片段:

$ echo $(( $(wc -l letter.txt | cut -c1-4)/66 + 1))

假设letter.txt存在并且有 66*4 行,那么这会将字符串 5 放在命令行上。现在我无法理解的是,根据我对命令行处理的了解,这个结论是如何得出的。

我的书(索贝尔的Linux 实用指南,4e)说

Bourne Again Shell 按以下顺序扫描每个标记以查找各种类型的扩展和替换。大多数这些过程将单词扩展为单个单词。只有大括号扩展、单词分割和路径名扩展可以更改命令中的单词数(变量“$@”的扩展除外 - 参见第 474 页)。

  1. 支撑扩展(下一页)
  2. 波形符扩展(第 368 页)
  3. 参数和变量扩展(第 368 页)
  4. 算术展开(第369页)
  5. 命令替换(第 371 页)
  6. 分词(第 372 页)
  7. 路径名扩展(第 372 页)
  8. 进程替换(第 374 页)
  9. 删除报价(第 374 页)

根据上述内容,算术扩展似乎会首先求值,如果是这样,则令牌$(wc -l letter.txt | cut -c1-4)对于 bash 处理的整数算术来说不是有效的操作数。我的出路是什么/我不明白什么?

答案1

你的书不完全正确。man bash具体顺序请参见:

展开的顺序是:大括号展开;波形符扩展、参数和变量扩展、算术扩展和命令替换(以从左到右的方式完成);分词;和路径名扩展。

注意逗号和的用法分号。参数、变量和算术扩展以及命令替换都以相同的顺序发生。

手册中关于算术扩展的说明如下:

表达式中的所有标记都会经历参数和变量扩展、命令替换和引号删除。

命令替换描述为

...在子shell环境中执行命令

这意味着所有扩展都是在从内向外嵌套时发生的。

$ echo $((1 + $(echo $((2+$(printf %s 3))))))
6

相关内容