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

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 -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:

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.

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

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?

19
задан Christian Hudon 9 September 2014 в 18:24
поделиться

3 ответа

Вы можете обработать список с помощью 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

(Делайте это во вложенной оболочке, чтобы не загромождать собственную среду.)

12
ответ дан 30 November 2019 в 02:04
поделиться

Многие программы, написанные на C, имеют тенденцию к сбою со строками со встроенными NUL, поскольку NUL завершает строку в стиле C. Если специально не написано, чтобы обращаться с ним.

Я обрабатываю /proc/*/environ в командной строке с помощью xargs:

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

Это дает вам одну переменную окружения на строку. Без команды xargs просто повторяет аргумент. Затем вы можете легко использовать grep, sed, awk и т. д., подключившись к нему.

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

Я использую это достаточно часто, поэтому у меня есть функция оболочки для этого:

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

Это дает вам среду определенного pid или самого себя, если аргумент не указан.

33
ответ дан 30 November 2019 в 02:04
поделиться

По какой-то причине 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 или используйте обходной путь.

2
ответ дан 30 November 2019 в 02:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: