2010-08-25 12 views
15

Estoy tratando de arrastrarme por el entorno de otros procesos para obtener un env var específico.Usar sed para obtener un env var de/proc/*/environment weirdness con x00

por lo que he estado tratando un comando sed como:

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

Pero estoy como salida el archivo completo Environ. Si se sustituye la \ 1 con sólo una cadena estática, lo entiendo cadena de caracteres más todo el archivo environ:

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

acabo debería llegar "blahblah" en el último ejemplo. Esto no sucede si me deshago de los caracteres nulos y uso algún otro conjunto de datos de prueba.

Esto me lleva a intentar transformar el \ x00 a \ x01 de, lo cual no parece funcionar:

cat /proc/pid/environ | tr '\000' '\001' | sed -n "s/\x01ENV_VAR_NAME=\([^\x01]*\)\x01/\1/p"

Me estoy perdiendo algo simple sobre sed aquí? ¿O debería seguir con esta solución?

Respuesta

12

Se puede procesar la lista con gawk, fijando el separador de registros a \0 y el separador de campo para =:

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

O usted podría utilizar read en un bucle para leer cada línea delimitada en nulo. Por ejemplo:

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

echo $ENV_VAR_NAME 

(hacer esto en un sub-shell para evitar clobbering su propio entorno.)

+0

Esto también soluciona mi problema con ir a tientas a juego con el primer env var en el archivo que no tiene un \ x01 delante de él. Muchas gracias. –

+0

Me salvaste el día. Creo que es la única forma de pasar un valor de variable dinámico a un servicio iniciado por el sistema. –

+0

'awk' no funciona si el valor de la variable contiene' = '? por ejemplo: 'awk -v 'RS = \ 0' -F = '$ 1 ==" LS_COLORS "{print $ 2}' Jasen

2

Por alguna razón sed no coincide con \ 0 con .

% 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 

Solución: no use sed o use su solución.

+0

grandes pasos de solución de problemas, gracias. –

31

Muchos programas escritos en C tienden a fallar con cadenas con NUL incrustados cuando un NUL termina una cadena de estilo C. A menos que esté escrito especialmente para manejarlo.

I proceso de/proc/*/environ en la línea de comandos con xargs:

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

Esto le da una env var por línea. Sin un comando, xargs simplemente echos el argumento. A continuación, puede usar grep, sed, awk, etc. fácilmente al conectarlo.

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

Puedo usar este a menudo que tengo una función de shell para ello:

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

Esto le da el ambiente de un PID específico, o uno mismo si no se proporciona ningún argumento.

+0

muy bueno. Nunca hubiera pensado usar xargs en este tipo de papel. Sin embargo, evité este tipo de solución al principio porque quería evitar cualquier problema con los valores de env var con \ n en ellos. –

+0

xargs le permite manejar fácilmente valores de varias líneas ejecutando un script o programa en cada argumento en lugar de simplemente hacer eco de él. De esta forma, cada argumento se puede procesar independientemente sabiendo que cada vez que se llama a su secuencia de comandos, se presenta con un valor único, independientemente de la cantidad de líneas que contenga. – camh

+0

¡Agradable! xargs también tiene un buen efecto secundario de recortar espacios en blanco. echo 'foo' | xargs | wc -C# => 4 – ppetraki

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

luego copia y pega según sea necesario.

+0

este código falla en las variables que contienen nuevas líneas, pero es corto. – Jasen

4

A pesar del muy viejo y respondió la pregunta, estoy añadiendo una oneliner muy simple, probablemente más sencillo para conseguir la salida de texto y su posterior procesamiento:

strings /proc/$PID/environ 
+0

Esta es una respuesta seriamente subestimada, hace que sea muy fácil insertarla en '| grep -E '^ (ENV_NAME) =' ' –