2010-08-25 2 views
15

Я пытаюсь пресечь некоторые другие процессы, чтобы получить конкретный env var.Использование sed для получения env var из/proc/*/environment weirdness с помощью x00

Так я пытался с 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"

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

ответ

12

Вы можете обрабатывать список с простаком, установив разделитель в \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 

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

+0

Это также решает мою проблему с шарить вокруг с соответствующими первым env var в файле, не имеющем \ x01 перед ним. Большое спасибо. –

+0

Ты спас мой день. Я думаю, что это единственный способ передать значение динамической переменной службе systemd-start. –

+0

'awk' не работает, если значение переменной содержит' = '? например: 'awk -v 'RS = \ 0' -F = '$ 1 ==" LS_COLORS "{print $ 2}' Jasen

2

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

+0

отличные шаги по устранению неполадок, спасибо. –

31

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

I процесс/Proc/*/окружать в командной строке с xargs:

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

Это дает один 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, или самостоятельно, если аргумент не подается.

+0

очень круто. Я бы никогда не думал использовать xargs в этой роли. Однако вначале я избегал этого типа решения, потому что я хотел избежать любых проблем с значениями env var с \ n в них. –

+0

xargs позволяет легко обрабатывать многострочные значения, запуская скрипт или программу для каждого аргумента, а не просто эхом. Таким образом, каждый аргумент может обрабатываться независимо, зная, что каждый раз, когда вы вызываете скрипт, он представляется с одним значением независимо от количества строк в нем. – camh

+0

Ницца! xargs также имеет хороший побочный эффект обрезания пробелов. echo 'foo' | xargs | wc -C# => 4 – ppetraki

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

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

+0

этот код не работает с переменными, содержащими символы новой строки, но он короткий. – Jasen

4

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

strings /proc/$PID/environ 
+0

Это серьезный недооцененный ответ, который делает его очень легким для труб в '| grep -E '^ (ENV_NAME) =' ' –