这个命令:
A=456 echo a random following command
类似于这个命令:
env A=456 echo a random following command
A 的新值 456 将仅用于 echo 命令。命令echo执行后,变量A恢复原值。
官方文档为Bash Reference Manual: Environment;正如它解释的那样:
任何简单命令或函数的环境都可以通过在其前面加上参数分配来临时扩充,如外壳参数中所述。这些赋值语句只影响该命令看到的环境。
更新 0x00
当我们运行以下命令时:
A=123
A=456 echo $A
输出仍然是123,而不是456。原因是 Bash 在执行命令 A=456 echo $A 之前会先评估 $A。所以命令:
A=456 echo $A
变成
A=456 echo 123
然后我们得到了输出123。
但下面的例子不同
A=123
A=456 eval echo '$A'
这个输出是456。
因为'$A' 是一个纯字符串,Bash 在运行命令之前不会评估它。当eval 命令运行时,变量A 被Bash 设置为456。
更新 0x01
子shell也是一个子进程,但是没有标记为导出的变量仍然可用于子shell。
Bash Reference Manual: Command Execution Environment,正如它解释的那样:
命令替换、用括号分组的命令和异步命令在作为 shell 环境副本的子 shell 环境中调用
A=123
( eval echo \$A )
输出为123。即使我们把(eval echo \$A)放到后台,输出仍然是123。
A=123
( eval echo \$A )&
当我们执行一个简单的命令,而不是一个内置或shell函数,比如执行一个脚本。此脚本在单独的 shell 环境中调用。只有标记为导出的 shell 变量可用于分离的环境。
A=123
bash -c 'echo A1=$A'
export A
bash -c 'echo A2=$A'
输出是:
A1=
A2=123