如何打印/回显环境变量?

问题描述 投票:39回答:4

如何打印刚设置的环境变量?

NAME=sam echo "$NAME" # empty

你可以在这里看到使用eval它的工作原理。这是这样的吗?

NAME=sam eval 'echo $NAME' # => sam
bash eval
4个回答
44
投票

这些需要作为不同的命令,例如:

NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"

在运行$NAME之前,将echo扩展为空字符串是由shell完成的,所以当NAME变量传递给echo命令的环境时,扩展已经完成(为null字符串)。

要在一个命令中获得相同的结果:

NAME=sam printenv NAME

8
投票

将现有答案与重要说明结合起来:

如上所述,NAME=sam echo "$NAME"的问题是$NAME在赋值NAME=sam生效之前被当前shell扩展。

保留原始语义的解决方案((无效)解决方案尝试NAME=sam echo "$NAME"):

使用eval [1](如问题本身)或printenv(由Aaron McDaid添加到heemayl's answer)或bash -c(来自Ljm Dullaart's answer),按效率降序排列:

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"'

printenv不是POSIX实用程序,但它可以在Linux和macOS / BSD上使用。

这种调用方式(<var>=<name> cmd ...)的作用是定义NAME

  • 作为环境变量
  • 这只是为被调用的命令定义的。

换句话说:NAME仅对被调用的命令存在,并且对当前shell没有影响(如果之前没有名为NAME的变量,则之后将不存在;预先存在的NAME变量保持不变)。

POSIX在其Command Search and Execution章节中定义了这种调用的规则。


以下解决方案的工作方式非常不同(来自heemayl's answer):

NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"

虽然它们产生相同的输出,但它们定义:

  • shell变量NAME(仅)而不是环境变量 如果echo是一个依赖于环境变量NAME的命令,它将不会被定义(或者可能与之前的定义不同)。
  • 在命令之后继续存在。

请注意,每个环境变量也作为shell变量公开,但反之则不正确:shell变量仅对当前shell及其子shell可见,但对子进程(如外部实用程序和(非源)脚本)不可见(除非它们用exportdeclare -x标记为环境变量)。


[1]从技术上讲,bash在这里违反了POSIX(和zsh一样):由于eval是一个内置的特殊shell,前面的NAME=sam赋值应该导致变量$NAME在命令完成后保留在范围内,但那不是怎么了。 但是,当您在POSIX兼容模式下运行bash时,它是兼容的。 dashksh始终是合规的。 确切的规则很复杂,有些方面需要由实现来决定;再次,请参阅Command Search and Execution。 此外,通常的免责声明适用:Use eval only on input you fully control or implicitly trust


2
投票

语法

variable=value command

通常用于为特定进程设置环境变量。但是,您必须了解哪个进程获取哪个变量以及谁解释它。例如,使用两个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'

第一个回声的结果为5,第二个回声的结果为3。


2
投票

这也适用于分号。

NAME=sam; echo $NAME

© www.soinside.com 2019 - 2024. All rights reserved.