我正在尝试通过命令调用具有修改环境的 shell 命令env。
根据说明书
env HELLO='Hello World' echo $HELLO
应该 echo Hello World,但事实并非如此。如果我做
HELLO='Hello World' bash -c 'echo $HELLO'
它按预期打印Hello World(感谢this answer for this info)。
我在这里想念什么?
干杯,尼克拉斯
我正在尝试通过命令调用具有修改环境的 shell 命令env。
根据说明书
env HELLO='Hello World' echo $HELLO
应该 echo Hello World,但事实并非如此。如果我做
HELLO='Hello World' bash -c 'echo $HELLO'
它按预期打印Hello World(感谢this answer for this info)。
我在这里想念什么?
干杯,尼克拉斯
这是因为在您的第一种情况下,您当前的 shell$HELLO在运行命令之前扩展了变量。HELLO并且您当前的 shell 中没有设置变量。
env HELLO='Hello World' echo $HELLO
会这样做:
$HELLO'HELLO=Hello World',因为当前 shell 中没有设置变量)'echo'''HELLOenv命令将运行并HELLO='Hello World'在其环境中设置env将echo使用参数''(空字符串)运行如您所见,当前 shell 扩展了$HELLO未设置的变量。
HELLO='Hello World' bash -c 'echo $HELLO'
会这样做:
HELLO='Hello World为以下命令设置变量'-c'和'echo $HELLO'echo $HELLO$HELLO为了在新的 bash 子 shell 中运行 echo ,bash 首先扩展它可以扩展的任何东西,$HELLO在这种情况下,父 shellHello World为我们设置它。echo 'Hello World'如果您尝试这样做:
env HELLO='Hello World' echo '$HELLO'
$HELLO是用单引号括起来的'HELLO=Hello World','echo'并且'$HELLO'HELLO='Hello World'在其环境中设置'$HELLO'在这种情况下,没有外壳可以扩展$HELLO,因此echo接收字符串$HELLO并打印出来。变量扩展仅由 shell 完成。
我想发生的事情类似于我也感到困惑的这种情况。
$HELLO简而言之,第一种情况下的变量扩展是由其环境中没有的当前 shell 完成的。但是,在第二种情况下,单引号会阻止当前 shell 进行变量扩展,因此一切都按预期工作。
请注意将单引号更改为双引号如何阻止此命令按您想要的方式工作:
HELLO='Hello World' bash -c "echo $HELLO"
现在这将失败,原因与您问题中的第一个命令相同。
这有效,对我有好处
$ MY_VAR='Hello' ANOTHER_VAR='World!!!' && echo "$MY_VAR $ANOTHER_VAR"
Hello World!!!
这是确认 shell 是否按预期工作的更简单方法。
env A=42 env
env
第一个命令设置A为 42 并运行env。第二个命令也运行env。比较两者的输出。
如前所述,传递给的变量的扩展echo发生在该变量设置之前。
较早的答案中尚未提到的一种替代方法是使用:
$ a=abc eval 'echo $a'
abc
$ echo $a
<blank>
请注意,您必须使用a=abc cmd语法而不是env a=abc cmd语法;显然env与内置的eval.