Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 394
Trevor Harrison Avatar asked Aug 25 '10 20:08

Trevor Harrison


People also ask

How do you use sed on a variable?

Another way to feed a literal text or a variable to stdin is by using here-string: $ sed 's/We/They/; s/Linux/Microsoft Windows/' <<< "We love Linux." They love Microsoft Windows. $ sed 's/We/They/; s/Linux/Microsoft Windows/' <<< $TEXT They love Microsoft Windows.

How do you replace a variable in a file using sed?

How SED Works. In the syntax, you only need to provide a suitable “new string” name that you want to be placed with the “old string”. Of course, the old string name needs to be entered as well. Then, provide the file name in the place of “file_name” from where the old string will be found and replaced.

What is Proc PID environ?

/proc/[pid]/environ This file contains the environment for the process. The entries are separated by null bytes ('\0'), and there may be a null byte at the end.


1 Answers

A lot of programs written in C tend to fail with strings with embedded NULs as a NUL terminates a C-style string. Unless specially written to handle it.

I process /proc/*/environ on the command line with xargs:

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

This gives you one env var per line. Without a command, xargs just echos the argument. You can then easily use grep, sed, awk, etc on that by piping to it.

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

I use this often enough that I have a shell function for it:

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

This gives you the environment of a specific pid, or self if no argument is supplied.

like image 58
camh Avatar answered Oct 07 '22 16:10

camh