$ a=one; echo $a
one
$ a=two echo $a
one
$ echo $a
one
a
的值会初始化为“2”,但为什么会显示“1”?
答案 0 :(得分:3)
env变量的相同行初始化仅适用于子shell。
从这些例子中可以更明显地看出:
unset a
a=two echo "<$a>"
<>
a=two bash -c 'echo "<$a>"'
<two>
echo "<$a>"
<>
在第二个片段中,它会打印<two>
,因为我们正在使用bash -c
生成一个子shell。
答案 1 :(得分:1)
这是由于shell处理替换和变量的顺序。根据{{3}}:
当需要执行给定的简单命令时(即,何时执行) 任何条件构造,例如AND-OR列表或case语句 没有绕过简单命令),以下扩展, 任务和重定向都应该从 命令文本的开头到结尾:
保存根据Shell语法规则识别为变量赋值或重定向的单词以进行处理 在第3步和第4步中。
应扩展非变量赋值或重定向的单词。如果任何字段在扩展后仍然存在,则第一个字段 字段应被视为命令名称,其余字段为 该命令的参数。
重定向应按重定向中所述执行。
- 醇>
每个变量赋值都应扩展为波形扩展,参数扩展,命令替换,算术扩展和 在分配值之前引用删除。
这意味着在参数扩展发生后执行变量分配,例如,在处理该命令的$a
变量赋值之前,a=
已展开。 a
的新值将传递到命令的执行环境中,但在这种情况下,echo
不会有任何用处。
如果你使用一个尚不存在的变量,你或许可以更好地看到正在发生的事情。
$ unset a
$ a=two echo \($a\)
()
$ a=one
$ a=two echo \($a\)
(one)
这是一个示例,您可以看到变量赋值被传递给执行的命令的执行环境:
$ a=one
$ a=two python -c 'import os;print(os.environ["a"])'
two