为什么shell中的赋值语句参数展开后不进行字段拆分?
Why does field splitting not occur after parameter expansion in an assignment statement in shell?
考虑以下两个作业。
$ 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]
After parameter expansion (Parameter Expansion), command substitution (Command Substitution), and arithmetic expansion (Arithmetic Expansion), the shell shall scan the results of expansions and substitutions that did not occur in double-quotes for field splitting and multiple fields can result.
那么在赋值语句中发生参数扩展时,POSIX 标准的哪一部分防止字段拆分?
在 2.9.1 中,"Simple Commands":
The words that are recognized as variable assignments or redirections according to Shell Grammar Rules are saved for processing in steps 3 and 4.
第 2 步——根据上述文本在这种情况下明确跳过——重申它在执行扩展和字段拆分时忽略赋值:
The words that are not variable assignments or redirections shall be expanded. If any fields remain following their expansion, the first field shall be considered the command name and remaining fields are the arguments for the command.
因此,第 2 步确定 运行 的命令(基于变量赋值和重定向以外的内容),它解决了您问题中给出的 b=$a
案例。
第 4 步执行其他扩展 - "tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal" - 用于分配。值得注意的是,字段拆分不是该集合的成员。事实上,在 2.6 中明确指出 none 这些词本身创建了多个词:
Tilde expansions, parameter expansions, command substitutions, arithmetic expansions, and quote removals that occur within a single word expand to a single field. It is only field splitting or pathname expansion that can create multiple fields from a single word. The single exception to this rule is the expansion of the special parameter '@' within double-quotes, as described in Special Parameters.
考虑以下两个作业。
$ 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]
After parameter expansion (Parameter Expansion), command substitution (Command Substitution), and arithmetic expansion (Arithmetic Expansion), the shell shall scan the results of expansions and substitutions that did not occur in double-quotes for field splitting and multiple fields can result.
那么在赋值语句中发生参数扩展时,POSIX 标准的哪一部分防止字段拆分?
在 2.9.1 中,"Simple Commands":
The words that are recognized as variable assignments or redirections according to Shell Grammar Rules are saved for processing in steps 3 and 4.
第 2 步——根据上述文本在这种情况下明确跳过——重申它在执行扩展和字段拆分时忽略赋值:
The words that are not variable assignments or redirections shall be expanded. If any fields remain following their expansion, the first field shall be considered the command name and remaining fields are the arguments for the command.
因此,第 2 步确定 运行 的命令(基于变量赋值和重定向以外的内容),它解决了您问题中给出的 b=$a
案例。
第 4 步执行其他扩展 - "tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal" - 用于分配。值得注意的是,字段拆分不是该集合的成员。事实上,在 2.6 中明确指出 none 这些词本身创建了多个词:
Tilde expansions, parameter expansions, command substitutions, arithmetic expansions, and quote removals that occur within a single word expand to a single field. It is only field splitting or pathname expansion that can create multiple fields from a single word. The single exception to this rule is the expansion of the special parameter '@' within double-quotes, as described in Special Parameters.