Jua*_*uan 13 shell bash environment-variables posix
以与多个实现一起使用的 posix 兼容方式,如何打印当前定义的环境变量列表而没有它们的值?
在某些实现(mksh、freebsd /bin/sh)上,仅使用export
本身就符合要求:
$ export
FOO2
FOO
Run Code Online (Sandbox Code Playgroud)
但是对于其他一些实现(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$
Run Code Online (Sandbox Code Playgroud)
其他选项如env
或printenv
没有选项只打印没有值的变量名,至少在我尝试过的 linux 和 freebsd 平台上没有。
管道到 awk/sed/等。或者使用参数扩展技术(例如,${foo%%=*}
)修剪列表是可以接受的,但它必须处理可能跨越行并且值中包含=
空格的值(参见上面的示例)。
特定于特定 shell 实现的答案很有趣,但我主要是在寻找跨实现兼容的东西。
Gil*_*il' 10
在 awk 中很容易。
awk 'BEGIN{for(v in ENVIRON) print v}'
Run Code Online (Sandbox Code Playgroud)
但是要注意一些 awk 实现会添加它们自己的环境变量(例如 GNU awk addAWKPATH
和AWKLIBPATH
to 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 /")"
Run Code Online (Sandbox Code Playgroud)
请注意,根据 shell,export -p
可能会或可能不会显示名称在 shell 中无效的变量,如果不是,则它可能会或可能不会正确引用名称。例如,dash、mksh 和 zsh 省略名称中包含换行符的变量,BusyBox dash 和 ksh93 将它们打印为原始值,而 bash 将它们打印为原始值而没有它们的值。如果您需要防御不受信任的输入,请不要依赖纯 POSIX 解决方案,也绝对不要调用eval
从export -p
.