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?
Вы можете обработать список с помощью 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
(Делайте это во вложенной оболочке, чтобы не загромождать собственную среду.)
Многие программы, написанные на 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 или самого себя, если аргумент не указан.
По какой-то причине 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 или используйте обходной путь.