我正在尝试通过命令调用具有修改环境的 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'
''
HELLO
env
命令将运行并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
.