¿Cómo imprimir/hacer eco de variables de entorno?
¿Cómo imprimo la variable de entorno que se acaba de configurar?
NAME=sam echo "$NAME" # empty
Puedes ver aquí eval
cómo funciona. ¿Es esta la forma?
NAME=sam eval 'echo $NAME' # => sam
Estos deben ir como comandos diferentes, por ejemplo:
NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"
La expansión $NAME
a una cadena vacía la realiza el shell antes de ejecutar echo
, por lo que en el momento en que la NAME
variable se pasa al echo
entorno del comando, la expansión ya está realizada (a una cadena nula).
Para obtener el mismo resultado en un comando:
NAME=sam printenv NAME
Para reunir las respuestas existentes con una aclaración importante:
Como se indicó, el problema NAME=sam echo "$NAME"
es que $NAME
el shell actual lo expande antes de que la asignación NAME=sam
entre 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"'
printenv
No 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: NAME
solo existe para el comando (proceso hijo) que se invoca y no tiene ningún efecto en el shell actual (si no NAME
existía ninguna variable nombrada antes, no habrá ninguna después; una NAME
variable 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 shell
NAME
(solamente) en lugar de una variable de entorno- si
echo
fuera un comando que dependiera de la variable de entornoNAME
, no estaría definido (o potencialmente definido de manera diferente a lo anterior).
- si
- 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 export
o declare -x
).
[1] Técnicamente, bash
aquí viola POSIX (tal como está zsh
): dado que eval
es un shell especial integrado, la NAME=sam
asignación anterior debería hacer que la variable $NAME
permanezca dentro del alcance después de que finalice el comando, pero eso no es lo que sucede.
Sin embargo, cuando se ejecuta bash
en modo de compatibilidad POSIX, es compatible.
dash
y ksh
siempre 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 eval
solo en entradas que controle totalmente o en las que confíe implícitamente .