posix shell:打印环境变量名称列表(不带值)

posix shell:打印环境变量名称列表(不带值)

以兼容多种实现的 posix 兼容方式,如何打印当前定义的环境变量列表没有他们的价值观?

在某些实现(mksh、freebsd /bin/sh)上,仅使用export本身就可以满足要求:

$ export
FOO2
FOO

但对于其他一些实现(bash、zsh、dash),export也会显示该值。以 bash 为例:

$ export
export FOO2='as  df\
  asdk=fja:\
asd=fa\
asdf'
export FOO='sjfkasjfd  kjasdf:\
   asdkj=fkajdsf:\
       :askjfkajsf=asdfkj:\
   safdkj'
$ printenv | sed -n l
FOO2=as\tdf\$
  asdk=fja:\$
asd=fa\$
asdf$
FOO=sjfkasjfd  kjasdf:\$
   asdkj=fkajdsf:\$
\t:askjfkajsf=asdfkj:\$
   safdkj$

其他选项如envor printenvdon't 具有仅打印不带值的变量名称的选项,至少在我尝试过的 linux 和 freebsd 平台上没有。

通过管道连接到 awk/sed/等。或使用参数扩展技术(例如,)修剪列表${foo%%=*}是可以接受的,但它必须处理可能跨越行并且=值中包含空格的值(请参见上面的示例)。

特定于特定 shell 实现的答案很有趣,但我主要是在寻找跨实现兼容的东西。

答案1

在 awk 中这非常简单。

awk 'BEGIN{for(v in ENVIRON) print v}'

但是要注意一些 awk 实现会添加自己的环境变量(例如 GNU awk 添加AWKPATHAWKLIBPATHto ENVIRON)。

如果环境变量的名称包含换行符,则输出不明确,这是极其不寻常的,但在技术上是可能的。纯粹的 sh 解决方案会很困难。你最好的选择是开始,export -p但是用纯 sh 按摩它是很困难的。您可以使用 sed 来处理 的输出export -p,然后使用eval来让 shell 删除它引用的内容。 Bash 和 zsh 打印非标准前缀。

report () { echo "${1%%=*}"; };
eval "$(export -p | sed "s/^export /report /;
                         s/^declare -x /report /;
                         s/typeset -x /report /")"

请注意,根据 shell 的不同,export -p可能会也可能不会显示名称在 shell 中无效的变量,如果不是,则可能会或可能不会正确引用名称。例如,dash、mksh 和 zsh 省略名称中包含换行符的变量,BusyBox dash 和 ksh93 原始打印它们,bash 原始打印它们而不包含它们的值。如果您需要防御不受信任的输入,请不要依赖纯 POSIX 解决方案,并且绝对不要调用evalexport -p.

答案2

我喜欢简单的事情;这适用于 POSIX 系统:

printenv | sed 's;=.*;;' | sort
HOME
HOSTNAME
PATH
PWD
SHLVL
TERM

答案3

这是我的解决方案,它可以很好地处理具有多行值的环境变量:

env -0 | cut -z -f1 -d= | tr '\0' '\n' | sort | column

这将使用 NUL 来打印环境来分隔变量而不是换行符 ( env -0)。

然后我们消除变量价值观using是第一个字段,cut -z -f1 -d=其中该-z选项指定以 NUL 分隔的记录,并表示字段由 分隔。-f1-d==

tr '\0' '\n'会将 NUL 分隔符转换为换行符。

然后我喜欢对变量名称进行排序并将它们显示在列中。

答案4

另一种方法是使用 grep:

printenv|grep -o "^[^=]\+"

相关内容