shell中的命令替换和字段拆分

时间:2015-03-05 16:02:54

标签: shell posix

我理解为什么以下命令失败。

$ a=foo bar
-bash: bar: command not found

尝试先执行a=foo然后执行失败的bar,因为没有名为bar的命令。

但我不明白为什么会这样。我期待以下命令也失败。

$ a=$(echo foo bar)
$ echo "$a"
foo bar

根据http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_05首先发生命令替换,然后发生字段拆分。

  

2.6 Word扩展

     

本节介绍了对其执行的各种扩展   话。并非所有扩展都在每个单词上执行,如中所述   以下部分。

     

Tilde扩展,参数扩展,命令替换,   算术扩展,以及在单个内发生的引用删除   单词扩展到单个字段。它只是字段拆分或路径名   可以从单个单词创建多个字段的扩展。该   这个规则的唯一例外是特殊的扩展   参数' @'在双引号内,如Special中所述   参数。

     

词扩展的顺序如下:

     
      
  1. Tilde扩展(参见Tilde Expansion),参数扩展(参见参数扩展),命令替换(参见命令替换),   算术扩展(参见算术扩展)应为   表演,开始结束。见令牌识别中的第5项。

  2.   
  3. 除非IFS为空,否则应对第1步生成的字段部分执行字段拆分(请参见字段拆分)。

  4.   
  5. 除非设置-f生效,否则应执行路径名扩展(请参阅路径名扩展)。

  6.   
  7. 报价删除(请参阅报价删除)应始终执行。

  8.   

所以在命令替换后,

a=$(echo foo bar)

变为

a=foo bar

然后在进行字段拆分后,应首先执行a=foo,然后执行bar,然后我们应该有相同的错误,即bar: command not found。为什么a=$(echo foo bar)可以正常工作?

1 个答案:

答案 0 :(得分:2)

答案在2.9.1 Simple Commands我相信。

具体点1和4:

  

1.保存根据Shell语法规则识别为变量赋值或重定向的单词,以便在步骤3和4中进行处理。

     

4.在分配值之前,应扩展每个变量赋值以进行波浪扩展,参数扩展,命令替换,算术扩展和引用删除。

3.4 Shell Parameters中的bash参考手册:

  

可以通过表单

的语句分配变量      

名称= [值]

     

如果未给出值,则为变量分配空字符串。所有值都经过波形扩展,参数和变量扩展,命令替换,算术扩展和引用删除(详见下文)。