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

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

NAME=sam echo "$NAME" # empty

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

NAME=sam eval 'echo $NAME' # => sam
382189 次浏览

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

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

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

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

NAME=sam printenv NAME

这对分号也有用。

NAME=sam; echo $NAME

语法

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'

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

将现有的答案与一项重要的澄清结合起来:

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

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

使用 eval < sup > [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"'

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

这种类型的调用(<var>=<name> cmd ...)所做的就是定义 NAME:

  • 作为一个 环境变量
  • 这是 < em > 仅为被调用的命令定义。

换句话说: NAME只存在于被调用的命令(子进程) ,而 对当前外壳没有影响(如果之前没有名为 NAME的变量存在,那么之后就没有了; 先前存在的 NAME变量保持不变)。

POSIX 在其 命令搜索和执行章节中定义了此类调用的规则。


以下解决方案的工作原理非常不同 (引自 Heemayl 的回答) :

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

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

  • Shell变量 NAME (only)而不是 环境变量
    • 如果 echo是一个依赖于 环境变量 NAME的命令,那么它就不会被定义(或者可能与之前的定义不同)。
  • 那个 在命令之后继续生活。

请注意,每个环境变量也是作为一个 shell 变量公开的,但是相反的情况并非如此: shell 变量只对当前 shell 及其子 shell 可见,而对子进程可见的是 没有,例如外部实用程序和(非源的)脚本(除非使用 exportdeclare -x将 shell 变量也指定为环境变量)。


[1]从技术上讲,bash在这里违反了 POSIX (就像 zsh一样) : 由于 eval是一个内置的 特别的 shell,前面的 NAME=sam赋值应该会导致变量 $NAME在命令完成之后保留在作用域中,但事实并非如此。
但是,当您在 POSIX 兼容模式下运行 bash时,它与 兼容。
dashksh总是兼容的。
确切的规则是复杂的,有些方面由实现来决定; 同样,请参见 命令搜索和执行
此外,通常的免责声明适用于: 仅在完全控制或隐式信任的输入时使用 eval

在窗口上,可以在 CLI 中使用此命令打印 C:\Users\dir\env | more

您可以使用 env 命令查看系统上设置的所有环境变量。这个列表很长,所以通过管道将输出通过 more 以使其更容易阅读。