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


75

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

NAME=sam echo "$NAME" # empty

您可以在这里使用eval它。是这样吗

NAME=sam eval 'echo $NAME' # => sam

2
NAME=sam echo whatever不会更改NAMEshell中的值。
rici

Answers:


82

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

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

$NAMEShell会在运行之前更早地将其扩展为空字符串echo,因此,在将NAME变量传递到echo命令环境时,扩展已经完成(至null字符串)。

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

NAME=sam printenv NAME

我添加了关于的注释printenv。希望一切顺利,@ heemayl
亚伦·麦克戴德

2
请注意,只有printenv-based命令保留了OP命令的语义:将其定义NAME命令范围的环境变量,只有被调用的命令及其子进程可以看到,而后续的shell命令则看不到。其他命令做的事情却大不相同:它们定义NAME为“直到当前外壳退出”仅外壳变量,所有后续的外壳命令都可以看到该变量,但没有外部实用程序
mklement0

14

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

如前所述,问题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"'

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

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

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

换句话说:NAME仅对于被调用的命令存在,并且对当前外壳无效(如果NAME之前没有命名的变量存在,则之后将没有任何NAME变量;先前存在的变量保持不变)。

POSIX在其POSIX中定义了这种调用的规则 命令搜索和执行”一章中。


以下解决方案的工作方式非常不同(与heemayl的答案相同):

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

当它们产生相同的输出时,它们改为定义:

  • 一个shell变量NAME(仅)而不是一个环境变量
    • 如果echo是依赖的命令环境变量NAME,则不会进行定义(或可能与之前的定义有所不同)。
  • 住在该命令后。

请注意,每个环境变量也都作为shell变量公开,但反之则不成立:shell变量仅对当前shell及其子shell可见,而对子进程可见,例如外部实用程序和(非源代码)脚本(除非它们被标记为带有export或将declare -x)。


[1]从技术上讲,bash这里违反了POSIX(按原样zsh):由于eval是内置的特殊Shell,因此前面的NAME=sam赋值应该使变量$NAME在命令完成后仍保留在作用域内,但这不会发生。
但是,当您bash以POSIX兼容模式运行时,它兼容的。
dash并且ksh始终合规。
确切的规则很复杂,某些方面要由实现决定。再次,请参阅命令搜索和执行
同样,通常的免责声明适用:仅在完全控制或隐式信任的输入上使用eval


4

语法

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。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.