为什么在shell中的赋值语句中参数扩展后不会发生字段拆分?

时间:2016-07-03 18:55:57

标签: shell posix variable-assignment

考虑以下两项任务。

$ a="foo  bar"
$ b=$a
$ b=foo  bar
bash: bar: command not found

为什么第二次分配工作正常?第二个命令与第三个命令有什么不同?

我希望第二项任务失败,因为

b=$a

将扩展为

b=foo  bar

由于$a不在双引号范围内,因此未引用foo bar,因此应按字段拆分(根据我的理解),这会导致b=foo被视为赋值和bar是一个无法找到的命令。

总结:我期望第二个命令失败的原因与导致第三个命令失败的原因相同。为什么第二个命令成功?

我浏览了POSIX,但是我无法找到任何指定在分配中发生参数扩展后不会发生字段拆分的内容。

我的意思是在参数扩展后的其他任何地方,对于不带引号的参数,会发生字段拆分。例如,

$ a="foo  bar"
$ printf "[%s] [%s]\n" $a
[foo] [bar]

请参阅Section 2.6.5

  

在参数扩展(参数扩展),命令替换(命令替换)和算术扩展(算术扩展)之后,shell应扫描用于字段拆分和多个字段的双引号中未出现的扩展和替换的结果可以结果。

当在赋值语句中发生参数扩展时,POSIX标准的哪一部分会阻止字段拆分?

1 个答案:

答案 0 :(得分:2)

在2.9.1,"简单命令":

  

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

步骤2 - 在这种情况下根据上述文本明确跳过 - 重申它在执行扩展和字段拆分时忽略赋值:

  

非变量分配或重定向的字词应予以扩展。如果任何字段在扩展后仍然存在,则第一个字段应被视为命令名称,其余字段是该命令的参数。

因此,它的第2步确定了要运行的命令(基于变量赋值和重定向以外的内容),它解决了问题中给出的b=$a个案。

步骤4执行其他扩展 - "代码扩展,参数扩展,命令替换,算术扩展和引用删除" - 用于作业。值得注意的是,字段拆分不是此集合的成员。实际上,它在2.6中是明确的,这些都不会在其中创造多个单词:

  

单个单词中出现的Tilde扩展,参数扩展,命令替换,算术扩展和引用删除扩展为单个字段。 只有字段拆分或路径名扩展才能从单个字创建多个字段。此规则的一个例外是扩展特殊参数' @'在双引号内,如特殊参数中所述。