Si examino /proc/1/environ
puedo ver una cadena delimitada por bytes nulos de 1
las variables de entorno del proceso . Me gustaría traer estas variables a mi entorno actual. ¿Hay una forma fácil de hacer esto?
La proc
página de manual me da un fragmento que ayuda a imprimir cada variable de entorno línea por línea (cat /proc/1/environ; echo) | tr '\000' '\n'
. Esto me ayuda a verificar que el contenido sea correcto, pero lo que realmente necesito hacer es obtener estas variables en mi sesión de bash actual.
¿Cómo puedo hacer eso?
fuente
. <(xargs -0 bash -c 'printf "export %q\n" "$@"' -- < /proc/nnn/environ)
, que también manejará las variables con comillas en ellas correctamente."$@"
lugar de'{}'
. Para aquellos que se preguntan sobre el--
argumento en su respuesta mejorada: los argumentos posicionales a los quebash -c command_string
se asignan comienzan en$0
, mientras que se"$@"
expanden para incluir argumentos que comienzan en$1
. El argumento--
se asigna a$0
.En
bash
puedes hacer lo siguiente. Esto funcionará para todos los contenidos posibles de las variables y evitaeval
:Esto declarará las variables leídas como variables de shell en el shell en ejecución. Para exportar las variables al entorno de shell en ejecución:
fuente
En esta respuesta, supongo que un sistema
/proc/$pid/environ
devuelve el entorno del proceso con el PID especificado, con bytes nulos entre las definiciones de variables. ( Entonces Linux, Cygwin o Solaris (?) ).Zsh
(Bastante simple como zsh: una redirección de entrada sin comando
<FILE
es equivalente acat FILE
. La salida de la sustitución del comando sufre expansión de parámetros con las banderas queps:\000:
significan "dividido en bytes nulos", y que@
significa "si todo está entre comillas dobles, entonces trate cada elemento de la matriz como un campo separado ”(generalizando"$@"
).)Bash, mksh
(En estos shells, un delimitador vacío pasado a
read
resultados en bytes nulos como separadores. Lo usoPWD
como un nombre de variable temporal para evitar tropezar con otra variable que podría terminar siendo importada. Si bien técnicamente también podría importarPWD
, solo permanecería allí hasta el siguientecd
)POSIX
La portabilidad POSIX no es tan interesante para esta pregunta, porque solo se aplica a los sistemas que tienen
/proc/PID/environ
. Entonces, la pregunta es qué admite Solaris sed, o si Solaris lo ha hecho/proc/PID/environ
, no solía hacerlo, pero estoy muy por detrás de la curva de las características de Solaris, por lo que podría ser hoy en día. En Linux, las utilidades GNU y BusyBox son a prueba de nulos, pero con advertencias.Si insistimos en la portabilidad POSIX, no se requiere ninguna de las utilidades de texto POSIX para manejar bytes nulos, por lo que esto es difícil. Aquí hay una solución que supone que awk admite un byte nulo como delimitador de registro (nawk y gawk lo hacen, al igual que BusyBox awk, pero mawk no).
BusyBox awk (que es la versión que se encuentra comúnmente en los sistemas embebidos Linux) hace nulo apoyo bytes, pero no establecer
RS
que"\0"
en unBEGIN
bloque y no la sintaxis de línea de comandos anterior; Sin embargo, es compatible-v 'RS="\0"'
. No he investigado por qué, esto parece un error en mi versión (Debian wheezy).(Ajuste todas las
líneasde registros separados por nulos en comillas simples"\047"
, después de escapar de las comillas simples dentro de los valores).Advertencias
Tenga en cuenta que cualquiera de estos puede intentar establecer variables de solo lectura (si su shell tiene variables de solo lectura).
fuente
Di vueltas y vueltas con esto. Estaba frustrado con la portabilidad de bytes nulos. No me sentó bien que no hubiera una forma confiable de manejarlos en un caparazón. Así que seguí buscando. La verdad es que encontré varias formas de hacer esto, solo algunas de las cuales se mencionan en mi otra respuesta. Pero los resultados fueron al menos dos funciones de shell que funcionan así:
Primero hablaré sobre la
\0
delimitación. En realidad es bastante fácil de hacer. Aquí está la función:Básicamente
od
tomastdin
y escribe enstdout
cada byte que recibe en hexadecimal uno por línea.Apuesto a que puedes adivinar cuál es el
\0null
, ¿verdad? Escrito así es fácil de manejar con cualquierased
.sed
solo guarda los dos últimos caracteres en cada línea hasta que encuentra un valor nulo en el que reemplaza las nuevas líneas intermedias conprintf
un código de formato amigable e imprime la cadena. El resultado es una\0null
matriz delimitada de cadenas de bytes hexadecimales. Mira:Lo canalicé arriba para
tee
que pueda ver tanto la salida de la suspensión del comando como el resultado delprintf
procesamiento. Espero que se dé cuenta de que la subshell en realidad tampoco se cita pero seprintf
divide solo en el\0null
delimitador. Mira:Tampoco hay citas sobre esa expansión, no importa si la citas o no. Esto se debe a que los valores de mordida no se separan, excepto la
\n
línea de línea generada por cada vez quesed
imprime una cadena. La división de palabras no se aplica. Y eso es lo que hace esto posible:La función anterior se utiliza
_zedlmt
para${pcat}
una secuencia preparada de código de bytes para el abastecimiento del entorno de cualquier proceso que se pueda encontrar en/proc
, o directamente.dot
${psrc}
al mismo en el shell actual, o sin un parámetro, para mostrar una salida procesada de la misma al terminal comoset
o loprintenv
haré. Todo lo que necesita es un$pid
: cualquier/proc/$pid/environ
archivo legible servirá.Lo usas así:
Pero, ¿cuál es la diferencia entre ser amigable con los humanos y el sourcable ? Bueno, la diferencia es lo que hace que esta respuesta sea diferente a todas las demás aquí, incluida la otra. Cualquier otra respuesta depende de las citas de shell de una forma u otra para manejar todos los casos límite. Simplemente no funciona tan bien. Por favor créeme, lo he intentado. Mira:
NINGUNA cantidad de caracteres extravagantes o comillas contenidas puede romper esto porque los bytes de cada valor no se evalúan hasta el momento en que se obtiene el contenido. Y ya sabemos que funcionó como un valor al menos una vez: no es necesario analizar o proteger la cotización aquí porque se trata de una copia byte por byte del valor original.
La función primero evalúa los
$var
nombres y espera a que se completen las comprobaciones antes de.dot
obtener el here-doc alimentado en el descriptor de archivo 3. Antes de obtenerlo, así es como se ve. Es infalible. Y POSIX portátil. Bueno, al menos el manejo de \ 0null es POSIX portable: el sistema de archivos / process es obviamente específico de Linux. Y es por eso que hay dos funciones.fuente
Uso
source
y sustitución de procesos :Dentro de poco:
Uso
eval
y sustitución de comandos :los
sed
llamada se puede reemplazar con unaawk
llamada:Pero no olvide que no borra ninguna variable de entorno que no esté en pid 1.
fuente
Vale la pena señalar que los procesos pueden tener variables de entorno que no son válidas Bash / Sh / * sh variables - POSIX recomienda pero no requiere que las variables de entorno tengan nombres coincidentes
^[a-zA-Z0-9_][a-zA-Z0-9_]*$
.Para generar una lista de variables que son compatibles con shell desde el entorno de otro proceso, en Bash:
Del mismo modo, para cargarlos:
Este problema surge solo ocasionalmente, pero cuando lo hace ...
fuente
Creo que esto es POSIX portátil:
Pero @Gilles hace un buen punto:
sed
probablemente manejará nulos, pero tal vez no. Así que también existe este método portátil POSIX (realmente lo creo esta vez) :Aún así, si tienes GNU
sed
solo necesitas hacer:Bueno, POSIX portable, excepto por el
/dev/...
que no está especificado, pero puede esperar que la sintaxis se comporte igual en la mayoría de los Unices.Ahora, si esto tiene algo que ver con su otra pregunta , puede usarlo así:
Here-doc es extremadamente útil porque evita que el shell se enrosque con cualquiera de las citas que trabajamos tan duro en el subshell y también nos proporciona una ruta confiable a un archivo
.dot
fuente en lugar de, nuevamente, un subshell o un shell variable. Otros aquí usan el bashism que funciona de la misma manera, solo que definitivamente es anónimo, mientras que POSIX solo especifica un para here-docs y, por lo tanto, puede ser cualquier tipo de archivo, aunque, en la práctica, generalmente es un archivo. ( por otro lado, utiliza anónimo para documentos aquí) . Sin embargo, lo desafortunado de la sustitución de procesos es que también depende de la shell, lo que podría ser un problema especialmente molesto si está trabajando .<(process substitution)
|pipe
iohere
temp
dash,
|pipes
init
Esto también funciona, por
|pipes
supuesto, pero luego pierde el entorno nuevamente al final cuando el|pipe's
estado se evapora con su subshell. Por otra parte, esto funciona:La
sed
declaración en sí funciona manteniendo cada línea en la memoria hasta que llegue a la última, momento en el que realiza una cita de manejo de reemplazo global e inserta nuevas líneas cuando sea apropiado anclando en los nulos. Bastante simple en realidad.En la
dash
imagen que verá, opté por evitar el \ mess y agregué la opciónGNU
específica . Pero eso es solo porque fue menos para escribir. Funciona de cualquier manera, como puedes ver en la imagen.-r
sed
zsh
Aquí está
zsh
:Y aquí está
dash
haciendo lo mismo:Incluso los escapes de terminales salen indemnes:
fuente
/proc/PID/environ
. Entonces, la pregunta es qué admite Solaris sed, o si Solaris lo ha hecho/proc/PID/environ
, no solía hacerlo, pero estoy seguro detrás de la curva de las características de Solaris para que pueda ser hoy en día.)sed
se requiere para manejar ascii hexadecimal, de los cuales el byte nulo es uno. Además, en realidad solo pensé si una forma mucho más fácil de hacer esto todavía.\xNN
sintaxis no es necesaria en POSIX, ni siquiera la\OOO
sintaxis octal (en cadenas C y en awk, sí, pero no en expresiones regulares sed)./proc/PID/environ
después de todo (tiene varias otras entradas similares a Linux/proc/PID
, pero noenviron
). Entonces, una solución portátil no necesita ir más allá de las herramientas de Linux, después de todo, lo que significa GNU sed o BusyBox sed. Ambos son compatibles\x00
con una expresión regular, por lo que su código es tan portátil como sea necesario (pero no POSIX). Sin embargo, es demasiado complejo.fuente