Why does field splitting not occur after parameter expansion in an assignment statement in shell?

為{幸葍}努か 提交于 2021-01-29 04:00:48

问题


Consider the following two assignments.

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

Why does the second assignment work fine? How is the second command any different from the third command?

I was hoping the second assignment to fail because

b=$a

would expand to

b=foo  bar

Since $a is not within double-quotes, foo bar is not quoted, therefore field-splitting should occur (as per my understanding) which would result in b=foo to be considered an assignment and bar to be a command that cannot be found.

Summary: I was expecting the 2nd command to fail for the same reason that caused the 3rd command to fail. Why does the 2nd command succeed?

I went through the POSIX but I am unable to find anything that specifies that field splitting won't occur after parameter expansion that occurs in an assignment.

I mean anywhere else field splitting would occur for an unquoted parameter after parameter expansion. For example,

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

See Section 2.6.5.

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.

So which part of the POSIX standard prevents field splitting when parameter expansion occurs in an assignment statement?


回答1:


In 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.

Step 2 -- which is explicitly skipped in this case per the above text -- reiterates that it ignores assignments when performing expansion and field splitting:

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.

Thus, it's step 2 that determines the command to run (based on contents other than variable assignments and redirections), which addresses the b=$a case given in your question.


Step 4 performs other expansions -- "tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal" -- for assignments. Notably, field splitting is not a member of this set. Indeed, it's explicit in 2.6 that none of these create multiple words in and of themselves:

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.



来源:https://stackoverflow.com/questions/38173313/why-does-field-splitting-not-occur-after-parameter-expansion-in-an-assignment-st

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!