'env'命令中'echo'命令的奇怪行为

10

当我尝试在“env”命令中回显变量时,我什么也看不到,但是使用“printenv”命令可以看到它:

root@devel:~# env xxx=23 echo $xxx

root@devel:~# env xxx=23 printenv | grep xxx
xxx=23

这里出了什么问题?

谢谢,我刚刚注意到了完全相同的事情。当你习惯了大多数最近的语言都变得懒散时,这有点令人不安。 - undefined
2个回答

17
env xxx=23 echo $xxx
在上面的示例中,shell在执行env之前会先计算$xxx。因此,没有任何输出被显示。
更详细地说,shell看到了四个单词envxxx=23echo$xxx。它将env解释为命令名称,并将xxx=23echo$xxx解释为三个参数,这些参数将传递给命令env。它在将$xxx传递给命令env之前先计算它。
相比之下,在下面的示例中,shell没有要计算的shell变量。相反,env以两个参数xxx=23printenv执行。 env设置环境变量xxx,然后执行printenv
$ env xxx=23 printenv | grep xxx
xxx=23

同样地,观察:

$ env xxx=23 sh -c 'echo $xxx'
23

由于$xxx被包含在单引号中,shell不会对其进行求值。取而代之的是使用四个参数运行env命令:xxx=23sh-cecho $xxx。在env设置环境变量xxx后,它将使用参数-cecho $xxx执行sh。当sh被执行时,$xxx被求值,因此它看到了变量xxx


3
当你运行env xxx=23 echo $xxx时,变量xxx=23echo进程执行期间变得可见。但是,在echo $xxx中,$xxx的值不是由echo评估的,而是由当前正在执行的shell评估的。由于env ...调用不会影响当前shell,因此$xxx的值是执行此命令之前它的值(可能未设置)。
使用echo不是测试env效果的好方法,因为您无法使echo命令打印其环境中定义的特定值。使用printenv的示例更好,因为它会转储它知道的环境变量的内容。另一个很好的测试是@john在他的答案中写的,调用另一个shell并使shell打印所选环境变量。任何具有打印环境变量内容能力的程序都可以工作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接