We know that in Bash, when a variable appears to the right of an assignment statement, the variable expands only and does not participle, even if there are no quotes on either side of the variable:
$ foo= "1 2" $ bar= $foo # will not be split into bar=1 and 22 words $ echo "$bar" 1 2 |
However, when a word that resembles an assignment statement is passed as a parameter to a command, the word-breaker step is no less:
$ foo= "1 2" $ printf '%s\n ' bar= $foo Bar=1 2 |
Bar= $foo Although it looks like an assignment statement, it is a normal argument because it appears after the command name. It expands into Bar=1 2 and is then split into bar=1 and 22 parameters passed to printf. The same is true for external commands:
$ valueofa= "1 b=2" $ env-i a= $VALUEOFA env # You thought the second parameter passed to Env was "a=1 b=2", but it was actually "a=1" and "b=2" two parameters A=1 b=2 |
However, some commands are special, such as Alias:
$ valueofa= "1 b=2" $ alias A= $valueOfa # to the alias command will be "a=1" and "b=2" two parameters? $ alias Alias a= ' 1 b=2 ' # is not, Valueofa this variable incredibly not be participle! |
There are 6 internal commands like alias: Alias, declare, typeset, export, ReadOnly, local, and their function is to declare something, a variable, or an alias. Bash treats their parameters in a special way, and if the format of the assignment statement is met, the variables in it are not participle. Of course you can also think of them as an assignment statement, but the effect of an assignment statement is to create a variable whose effect is to create a variable (in addition to the alias command). Bash manuals also directly call them assignment statements:
Assignment statements may also appear as arguments to the,,,, alias declare typeset export readonly , and local builtin commands.
In Bash's implementation, special handling of such parameters is specifically done with a function:
/* This was a hack to suppress word splitting for assignment statements */ Static void fix_assignment_words (words) *words; {
...
Wait, it's not over yet. It says that if the assignment statement is satisfied with the format, these parameters will be treated in a special way, if not satisfied?
We know that the left side of an assignment statement must be a valid identifier, and a valid identifier conforms to the letter underscore followed by a number of alphanumeric underscores. In this case, 1= $foo must not be a valid assignment statement, the following test:
$ foo= "1 2=2" $ alias 1= $foo $ alias Alias 1 = ' 1 ' Alias 2 = ' 2 ' |
Sure enough, it was treated as an ordinary parameter.
Parameters that resemble assignment statements