Использование sed для получения переменной env из / proc / * / environment странности с \ x00 - PullRequest
18 голосов
/ 26 августа 2010

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

Поэтому я пробовал команду 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"

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

Ответы [ 5 ]

33 голосов
/ 26 августа 2010

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

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

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

Это дает вам один var env на строку.Без команды 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, если не указан аргумент.

12 голосов
/ 26 августа 2010

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

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

10 голосов
/ 18 сентября 2015
cat /proc/PID/environ  | tr '\0' '\n' | sed 's/^/export /' ; 

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

9 голосов
/ 27 октября 2017

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

strings /proc/$PID/environ
2 голосов
/ 26 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...