¿Cómo imprimir/hacer eco de variables de entorno?

Resuelto Christian asked hace 8 años • 0 respuestas

¿Cómo imprimo la variable de entorno que se acaba de configurar?

NAME=sam echo "$NAME" # empty

Puedes ver aquí evalcómo funciona. ¿Es esta la forma?

NAME=sam eval 'echo $NAME' # => sam
Christian avatar Oct 15 '16 02:10 Christian
Aceptado

Estos deben ir como comandos diferentes, por ejemplo:

NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"

La expansión $NAMEa una cadena vacía la realiza el shell antes de ejecutar echo, por lo que en el momento en que la NAMEvariable se pasa al echoentorno del comando, la expansión ya está realizada (a una cadena nula).

Para obtener el mismo resultado en un comando:

NAME=sam printenv NAME
heemayl avatar Oct 14 '2016 19:10 heemayl

Para reunir las respuestas existentes con una aclaración importante:

Como se indicó, el problema NAME=sam echo "$NAME"es que $NAMEel shell actual lo expande antes de que la asignación NAME=samentre en vigor.

Soluciones que preservan la semántica original (del intento de solución (ineficaz) NAME=sam echo "$NAME"):

Utilice eval[1] (como en la pregunta misma), o printenv(como lo agregó Aaron McDaid a la respuesta de heemayl ), o bash -c(de la respuesta de Ljm Dullaart ), en orden descendente de eficiencia:

NAME=sam eval 'echo "$NAME"'  # use `eval` only if you fully control the command string
NAME=sam printenv NAME
NAME=sam bash -c 'echo "$NAME"'

printenvNo es una utilidad POSIX, pero está disponible tanto en Linux como en macOS/BSD.

Lo que hace este estilo de invocación ( <var>=<name> cmd ...) es definir NAME:

  • como variable de entorno
  • que sólo se define para el comando que se invoca .

En otras palabras: NAMEsolo existe para el comando (proceso hijo) que se invoca y no tiene ningún efecto en el shell actual (si no NAMEexistía ninguna variable nombrada antes, no habrá ninguna después; una NAMEvariable preexistente permanece sin cambios).

POSIX define las reglas para este tipo de invocación en su capítulo Búsqueda y ejecución de comandos .


Las siguientes soluciones funcionan de manera muy diferente (citadas de la respuesta de heemayl ):

NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"

Si bien producen el mismo resultado , en su lugar definen:

  • una variable de shellNAME (solamente) en lugar de una variable de entorno
    • si echofuera un comando que dependiera de la variable de entornoNAME , no estaría definido (o potencialmente definido de manera diferente a lo anterior).
  • que sigue vivo después del comando.

Tenga en cuenta que cada variable de entorno también se expone como una variable de shell, pero lo contrario no es cierto: las variables de shell solo son visibles para el shell actual y sus subshells, pero no para los procesos secundarios, como utilidades externas y scripts (sin fuente). (a menos que las variables de shell estén designadas como variables de entorno (también) con exporto declare -x).


[1] Técnicamente, bashaquí viola POSIX (tal como está zsh): dado que evales un shell especial integrado, la NAME=samasignación anterior debería hacer que la variable $NAMEpermanezca dentro del alcance después de que finalice el comando, pero eso no es lo que sucede.
Sin embargo, cuando se ejecuta bashen modo de compatibilidad POSIX, es compatible.
dashy kshsiempre cumplen.
Las reglas exactas son complicadas y algunos aspectos se dejan a criterio de las implementaciones; Nuevamente, consulte Búsqueda y ejecución de comandos .
Además, se aplica el descargo de responsabilidad habitual: Úselo evalsolo en entradas que controle totalmente o en las que confíe implícitamente .

mklement0 avatar Oct 15 '2016 16:10 mklement0