如何打印刚设置的环境变量?
NAME=sam echo "$NAME" # empty
Run Code Online (Sandbox Code Playgroud)
你可以看到这里使用eval它的工作原理.这是这样的吗?
NAME=sam eval 'echo $NAME' # => sam
Run Code Online (Sandbox Code Playgroud)
hee*_*ayl 52
这些需要作为不同的命令,例如:
NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"
Run Code Online (Sandbox Code Playgroud)
$NAME在运行之前,由shell先完成对空字符串的扩展echo,因此在将NAME变量传递给echo命令的环境时,扩展已经完成(为空字符串).
要在一个命令中获得相同的结果:
NAME=sam printenv NAME
Run Code Online (Sandbox Code Playgroud)
将现有答案与重要说明结合在一起:
如前所述,问题NAME=sam echo "$NAME"在于在赋值生效之前$NAME,当前的shell会对其进行扩展。NAME=sam
保留原始语义的解决方案(无效尝试的尝试NAME=sam echo "$NAME"):
使用eval[1]
(如问题本身),或printenv(按Aaron McDaid在heemayl的答案中所添加的)或bash -c((根据Ljm Dullaart的答案)按效率降序排列:
NAME=sam eval 'echo "$NAME"' # use `eval` only if you fully control the command string
NAME=sam printenv NAME
NAME=sam bash -c 'echo "$NAME"'
Run Code Online (Sandbox Code Playgroud)
printenv 不是POSIX实用程序,但在Linux和macOS / BSD上均可用。
这种调用方式(<var>=<name> cmd ...)的作用是定义NAME:
换句话说:NAME仅对于被调用的命令存在,并且对当前外壳无效(如果NAME之前没有命名的变量存在,则之后将没有任何NAME变量;预先存在的变量保持不变)。
POSIX在“ 命令搜索和执行”一章中定义了这种调用的规则。
以下解决方案的工作方式非常不同(与heemayl的答案相同):
NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"
Run Code Online (Sandbox Code Playgroud)
当它们产生相同的输出时,它们定义:
NAME(只),而不是一个环境变量
echo是依赖于环境变量的命令NAME,则不会进行定义(或可能与之前的定义有所不同)。请注意,每个环境变量也都作为shell变量公开,但反之则不成立:shell变量仅对当前shell及其子shell可见,而对子进程不可见,例如外部实用程序和(非源代码)脚本(除非使用export或将它们标记为环境变量declare -x)。
[1]从技术上讲,bash这里违反了POSIX(按原样zsh):由于eval是内置的特殊 Shell,因此前面的NAME=sam赋值应该使变量$NAME在命令完成后仍保留在作用域中,但这不会发生。
但是,当您bash以POSIX兼容模式运行时,它是兼容的。
dash并且ksh始终合规。
确切的规则很复杂,并且某些方面要由实现决定。再次,请参阅命令搜索和执行。
同样,通常的免责声明适用:仅在完全控制或隐式信任的输入上使用eval。
语法
variable=value command
Run Code Online (Sandbox Code Playgroud)
通常用于为特定进程设置环境变量。但是,您必须了解哪个进程获取哪个变量以及谁解释它。例如,使用两个 shell:
a=5
# variable expansion by the current shell:
a=3 bash -c "echo $a"
# variable expansion by the second shell:
a=3 bash -c 'echo $a'
Run Code Online (Sandbox Code Playgroud)
第一个回波的结果将为 5,第二个回波的结果将为 3。
| 归档时间: |
|
| 查看次数: |
90138 次 |
| 最近记录: |