Использование sed для получения env var из /proc/ */environment weirdness с\x00

Я пытаюсь разбираться в какой-то другой среде процессов, чтобы получить конкретный env var.

Итак, я пытался выполнить команду sed, например:

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

Но я получаю как вывод полный файл окружения. Если я заменил \1 только статической строкой, я получу эту строку плюс весь файл окружения:

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"

Я пропустил что-то простое о седе здесь? Или я должен просто придерживаться этого обходного пути?

Ответы

Ответ 1

Вы можете обработать список с помощью gawk, установив разделитель записей на \0 и разделитель полей на =:

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

Или вы могли бы использовать read в цикле, чтобы читать каждую строку с нулевым разделителем. Например:

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

echo $ENV_VAR_NAME

(Сделайте это в суб-оболочке, чтобы избежать слияния собственной среды.)

Ответ 2

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

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

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'

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

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

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

Ответ 3

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

затем скопируйте и вставьте по мере необходимости.

Ответ 4

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

Ответ 5

Несмотря на действительно старый и ответный вопрос, я добавляю один очень простой oneliner, возможно, более простой для получения текста и дальнейшей обработки:

strings /proc/$PID/environ