具有多行值的环境变量可能会混淆env
的输出:
# export A="B
> C=D
> E=F"
# env
A=B
C=D
E=F
TERM=xterm
SHELL=/bin/bash
USER=root
MAIL=/var/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/root
LANG=en_US.UTF-8
PS1=\h:\w\$
SHLVL=1
HOME=/root
LOGNAME=root
_=/usr/bin/env
在这种情况下,无法仅使用awk -F=
提取所有名称,因为它显示错误的名称C
和E
:
# env | awk -F= '{print $1}'
A
C
E
TERM
SHELL
USER
MAIL
PATH
PWD
LANG
PS1
SHLVL
HOME
LOGNAME
_
然后我发现env
支持标记-0
以0字节而不是换行结束每个输出行,因此使用sed
我可以切断bash
中的值}:
# env -0 | sed -e ':a;N;$!ba;s/\([^=]\+\)=\([^\x00]*\)\x00/\1\n/g'
A
TERM
SHELL
USER
MAIL
PATH
PWD
LANG
PS1
SHLVL
HOME
LOGNAME
_
但是BusyBox的env
does not support标记为-0
。还有其他办法吗?
答案 0 :(得分:3)
如果你使用的是linux(我认为busybox只在linux上运行,但我可能错了),/proc/self/environ
包含一个与env -0
相同的NUL分隔环境。您可以将env -0 |
替换为< /proc/self/environ
。
sed -e ':a;N;$!ba;s/\([^=]\+\)=\([^\x00]*\)\x00/\1\n/g' < /proc/self/environ
答案 1 :(得分:2)
这可能不是一个优雅但有效的解决方案。它首先从env
的输出中提取所有可能的名称,然后使用shell的扩展${parameter:+word}
验证每个名称。最后它删除了重复项,因为相同的变量名可以打印在env
输出中的几行上(作为实际变量名称和其他变量的多行值的一部分):
env | awk -F= '/[a-zA-Z_][a-zA-Z_0-9]*=/ {
if (!system("[ -n \"${" $1 "+y}\" ]")) print $1 }' | sort | uniq
PS:| sort | uniq
部分也可以在awk
中实现。
答案 2 :(得分:0)
如果您的环境变量 values 包含空值,这将中断。但这也会破坏POSIX的兼容性。
所以它应该起作用。
...除非您希望遇到包含换行符的环境变量 names 。在这种情况下,换行符在显示时将被截断。但是我似乎无法理解如何在busybox外壳中创建带有换行符的环境变量。我的当地炮弹不惜一切代价。因此,我认为这不是大问题。就POSIX所说,Other characters may be permitted by an implementation; applications shall tolerate the presence of such names.
因此,可以容忍。
# Read our environment; it's delimited by null bytes.
# Remove newlines
# Replace null bytes with newlines
# On each line, grab everything before the first '='
cat /proc/self/environ | tr -d '\n' | tr '\0' '\n' | cut -d '=' -f 1