使用sed从\ x00获取/ proc / * / environ古怪的env变量

时间:2010-08-25 20:03:59

标签: linux bash sed environment-variables

我正试图通过其他一些进程环境来获取特定的env var。

所以我一直在尝试像:

这样的sed命令

sed -n "s/\x00ENV_VAR_NAME=\([^\x00]*\)\x00/\1/p" /proc/pid/environ

但是我将输出完整的environ文件。如果我用一个静态字符串替换\ 1,我会得到该字符串加上整个environ文件:

sed -n "s/\x00ENV_VAR_NAME=\([^\x00]*\)\x00/BLAHBLAH/p" /proc/pid/environ

我应该在最后一个例子中得到“BLAHBLAH”。如果我摆脱空字符并使用其他一些测试数据集,就不会发生这种情况。

这引导我尝试将\ x00转换为\ x01,这似乎有效:

cat /proc/pid/environ | tr '\000' '\001' | sed -n "s/\x01ENV_VAR_NAME=\([^\x01]*\)\x01/\1/p"

我在这里错过了关于sed的简单介绍吗?或者我应该坚持这个解决方法?

5 个答案:

答案 0 :(得分:33)

许多用C语言编写的程序往往会因嵌入NUL的字符串而失败,因为NUL终止了一个C风格的字符串。除非专门为处理它而写。

我使用xargs:

在命令行上处理/ proc / * / environ
xargs -n 1 -0 < /proc/pid/environ

这为每行提供了一个env var。没有命令,xargs只是回应了这个论点。然后你就可以通过管道来轻松地使用grep,sed,awk等。

xargs -n 1 -0 < /proc/pid/environ | sed -n 's/^ENV_VAR_NAME=\(.*\)/\1/p'

我经常使用它,因为我有一个shell函数:

pidenv() 
{ 
    xargs -n 1 -0 < /proc/${1:-self}/environ
}

这为您提供了特定pid的环境,如果没有提供参数,则为self。

答案 1 :(得分:12)

您可以使用gawk处理列表,将记录分隔符设置为\0,将字段分隔符设置为=

gawk -v 'RS=\0' -F= '$1=="ENV_VAR_NAME" {print $2}' /proc/pid/environ

或者您可以在循环中使用read来读取每个NUL分隔的行。例如:

while read -d $'\0' ENV; do declare "$ENV"; done < /proc/pid/environ

echo $ENV_VAR_NAME

(在子shell中执行此操作以避免破坏自己的环境。)

答案 2 :(得分:10)

cat /proc/PID/environ  | tr '\0' '\n' | sed 's/^/export /' ; 

然后根据需要进行复制和粘贴。

答案 3 :(得分:9)

尽管有一个非常陈旧且回答的问题,但我添加了一个非常简单的oneliner,可能更简单,可以获得文本输出和进一步处理:

strings /proc/$PID/environ

答案 4 :(得分:2)

由于某些原因,sed与\ 0 .

不匹配
% echo -n "\00" | xxd
0000000: 00                                       .
% echo -n "\00" | sed 's/./a/g' | xxd
0000000: 00                                       .
% echo -n "\01" | xxd                
0000000: 01                                       .
% echo -n "\01" | sed 's/./a/g' | xxd
0000000: 61                                       a

解决方案:请勿使用sed或使用您的解决方法。