bash 使用 sed 从带有 \x00 的 /proc/*/environ 怪异中获取环境变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3569784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:31:44  来源:igfitidea点击:

Using sed to get an env var from /proc/*/environ weirdness with \x00

linuxbashsedenvironment-variables

提问by Trevor Harrison

I'm trying to grovel through some other processes environment to get a specific 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:

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

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 的简单信息吗?或者我应该坚持这个解决方法?

采纳答案by John Kugelman

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

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

gawk -v 'RS=
while read -d $'
xargs -n 1 -0 < /proc/pid/environ
' ENV; do declare "$ENV"; done < /proc/pid/environ echo $ENV_VAR_NAME
' -F= '=="ENV_VAR_NAME" {print }' /proc/pid/environ

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

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

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

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

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

回答by camh

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.

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

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

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

pidenv() 
{ 
    xargs -n 1 -0 < /proc/${1:-self}/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 等。

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

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

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

% echo -n "##代码##" | xxd
0000000: 00                                       .
% echo -n "##代码##" | sed 's/./a/g' | xxd
0000000: 00                                       .
% echo -n "" | xxd                
0000000: 01                                       .
% echo -n "" | sed 's/./a/g' | xxd
0000000: 61                                       a

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

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

回答by Jasen

##代码##

then copy and paste as needed.

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

回答by Petr Matousu

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,可能更容易获取文本输出和进一步处理:

##代码##

回答by unbeli

For some reason sed does not match \0 with .

由于某种原因 sed 与 \0 不匹配 .

##代码##

Solution: do not use sed or use your workaround.

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