你如何确定是否导出shell变量?

Sho*_*adz 17 shell bash

在 Bourne shell 系列中,shell 变量都具有大写名称;这意味着您无法仅通过查看其名称来判断特定变量是否为环境变量。您如何确定哪些 Bourne shell 变量是本地的(仅在当前 shell 中定义)?

Eli*_*gan 30

最便携的方式是export -p.

export -p列出导出的变量。这通常是这样的declare -x如果你的 shell 有declare.

当前使用的 Bourne 风格的 shell 应该支持export -p,因为它是POSIX要求的

当指定-p 时export应将所有导出变量的名称和值写入标准输出,格式如下:

"export %s=%s\n", <name>, <value>
Run Code Online (Sandbox Code Playgroud)

如果设置了名称,并且:

"export %s\n", <name>
Run Code Online (Sandbox Code Playgroud)

如果名称未设置。

标准继续解释变量值的显示方式通常允许它稍后在=赋值的右侧使用。这就是说它可以被引用。不同的外壳可能会以不同的方式显示它们,但具有相同的效果。export -p即使在没有declare内置的shell 中也能工作,比如Dash

"export %s=%s\n", <name>, <value>
Run Code Online (Sandbox Code Playgroud)
"export %s\n", <name>
Run Code Online (Sandbox Code Playgroud)

我已经将输出通过管道传输到grep紧凑性,但是如果您不对其进行过滤,那么您将获得导出变量的完整列表。从你的问题来看,这听起来可能是你最有用的。

某些 shell(如 Bash)使用非标准格式,除非明确指示以符合 POSIX 的方式运行。在 Bash 中export -p,输出与declare -x默认情况下相同。

$ dash -c 'export -p | grep HOME='  # busybox sh and other ash give the same output.
export HOME='/home/ek'
Run Code Online (Sandbox Code Playgroud)
$ posh -c 'export -p | grep HOME='  # ksh93, mksh, lksh, and others give the same output.
export HOME=/home/ek
Run Code Online (Sandbox Code Playgroud)
$ bash -c 'export -p | grep HOME='
declare -x HOME="/home/ek"
Run Code Online (Sandbox Code Playgroud)
$ bash -c 'POSIXLY_CORRECT= export -p | grep HOME='
export HOME="/home/ek"
Run Code Online (Sandbox Code Playgroud)
$ bash -c 'set -o posix; export -p | grep HOME='
export HOME="/home/ek"
Run Code Online (Sandbox Code Playgroud)

即使启用了 POSIX 兼容性,Zsh 也会显示非标准格式:

$ bash --posix -c 'export -p | grep HOME='
export HOME="/home/ek"
Run Code Online (Sandbox Code Playgroud)
$ ln -s /bin/bash sh
$ ./sh -c 'export -p | grep HOME='  # Invoking bash as sh also puts it in POSIX mode.
export HOME="/home/ek"
Run Code Online (Sandbox Code Playgroud)
$ zsh -c 'export -p | grep HOME='
typeset -x HOME=/home/ek
Run Code Online (Sandbox Code Playgroud)

在任何情况下,您都可以通过搜索后跟=. 这不依赖于行上的先前单词,只要它们不紧跟在 之前=,它们不应该如此。例如:

% export -p | grep -oE '\w+=.*'
HOME=/home/ek
LANG=en_US.UTF-8
LESSCLOSE='/usr/bin/lesspipe %s %s'
....
Run Code Online (Sandbox Code Playgroud)

请注意,并非所有条目都必须具有=. 这是因为变量可以取消设置但可以导出。这些条目被grep上面的命令过滤掉了,这可能是也可能不是你想要的。

大多数时候,你只是想检查输出,因此,如果条目由之前你不会在意exportdeclare -xtypeset -x,或别的东西。然后就跑export -p

我在 Ubuntu 16.04 LTS 上使用每个 shell 的官方打包版本测试了这些命令。


mur*_*uru 19

如果您想查看变量是否已导出,请使用declare

$ foo=a bar=b
$ export foo
$ declare -p foo bar
declare -x foo="a"
declare -- bar="b"
Run Code Online (Sandbox Code Playgroud)