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

时间:2022-06-01 18:54:57

I'm trying to grovel through some other processes environment to get a specific env var.

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

So I've been trying a sed command like:

所以我一直在尝试像以下一样的sed命令:

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

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

But I'm getting as output the full environ file. If I replace the \1 with just a static string, I get that string plus the entire environ file:

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

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

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

I should just be getting "BLAHBLAH" in the last example. This doesn't happen if I get rid of the null chars and use some other test data set.

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

This lead me to try transforming the \x00 to \x01's, which does seem to work:

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

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

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

Am I missing something simple about sed here? Or should I just stick to this workaround?

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

5 个解决方案

#1


12  

You could process the list with gawk, setting the record separator to \0 and the field separator to =:

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

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

Or you could use read in a loop to read each NUL-delimited line. For instance:

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

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

echo $ENV_VAR_NAME

(Do this in a sub-shell to avoid clobbering your own environment.)

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

#2


32  

A lot of programs written in C tend to fail with strings with embedded NULs as a NUL terminates a C-style string. Unless specially written to handle it.

由于NUL终止了C风格的字符串,许多用C语言编写的程序往往会因嵌入NUL的字符串而失败。除非特别写下来处理它。

I process /proc/*/environ on the command line with xargs:

我使用xargs在命令行上处理/ proc / * / environ:

xargs -n 1 -0 < /proc/pid/environ

This gives you one env var per line. Without a command, xargs just echos the argument. You can then easily use grep, sed, awk, etc on that by piping to it.

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

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

I use this often enough that I have a shell function for it:

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

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

This gives you the environment of a specific pid, or self if no argument is supplied.

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

#3


10  

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

then copy and paste as needed.

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

#4


6  

In spite of really old and answered question, I am adding one very simple oneliner, probably simpler for getting the text output and further processing:

尽管有一个非常古老和回答的问题,我正在添加一个非常简单的oneliner,可能更简单的获取文本输出和进一步处理:

strings /proc/$PID/environ

#5


2  

For some reason sed does not match \0 with .

出于某种原因,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

Solution: do not use sed or use your workaround.

解决方案:不要使用sed或使用您的解决方法。

#1


12  

You could process the list with gawk, setting the record separator to \0 and the field separator to =:

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

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

Or you could use read in a loop to read each NUL-delimited line. For instance:

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

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

echo $ENV_VAR_NAME

(Do this in a sub-shell to avoid clobbering your own environment.)

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

#2


32  

A lot of programs written in C tend to fail with strings with embedded NULs as a NUL terminates a C-style string. Unless specially written to handle it.

由于NUL终止了C风格的字符串,许多用C语言编写的程序往往会因嵌入NUL的字符串而失败。除非特别写下来处理它。

I process /proc/*/environ on the command line with xargs:

我使用xargs在命令行上处理/ proc / * / environ:

xargs -n 1 -0 < /proc/pid/environ

This gives you one env var per line. Without a command, xargs just echos the argument. You can then easily use grep, sed, awk, etc on that by piping to it.

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

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

I use this often enough that I have a shell function for it:

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

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

This gives you the environment of a specific pid, or self if no argument is supplied.

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

#3


10  

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

then copy and paste as needed.

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

#4


6  

In spite of really old and answered question, I am adding one very simple oneliner, probably simpler for getting the text output and further processing:

尽管有一个非常古老和回答的问题,我正在添加一个非常简单的oneliner,可能更简单的获取文本输出和进一步处理:

strings /proc/$PID/environ

#5


2  

For some reason sed does not match \0 with .

出于某种原因,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

Solution: do not use sed or use your workaround.

解决方案:不要使用sed或使用您的解决方法。