No busques más en otras webs porque llegaste al espacio exacto, contamos con la respuesta que deseas y sin complicarte.
Solución:
Estos deben ir como diferentes comandos, por ejemplo:
NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"
La expansión $NAME
para vaciar string lo hace el shell antes, antes de ejecutar echo
, por lo que en ese momento el NAME
la variable se pasa al echo
entorno de comando, la expansión ya está hecha (para null string).
Para obtener el mismo resultado en un comando:
NAME=sam printenv NAME
Para unir las respuestas existentes con una aclaración importante:
Como se dijo, el problema de NAME=sam echo "$NAME"
es eso $NAME
se expande por el shell actual antes de asignación NAME=sam
Toma efecto.
Soluciones que preservan la semántica original (del (ineficaz) intento de solución NAME=sam echo "$NAME"
):
Utilizar cualquiera 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 este estilo de invocación (=
) hace es definir NAME
:
- como un ambiente variable
- es decir solo definido para el comando que se invoca.
En otras palabras: NAME
sólo existe para el comando que se invoca, y no tiene efecto en el shell actual (si no se nombra ninguna variable NAME
existido antes, no lo habrá después; un preexistente NAME
variable 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. (de la respuesta de heemayl):
NAME=sam; echo "$NAME"
NAME=sam && echo "$NAME"
Mientras producen lo mismo producción, en su lugar definen:
- a cáscara variable
NAME
(solamente) en lugar de un ambiente variable- Si
echo
eran un comando que dependía de ambiente variableNAME
, no se definiría (o se definiría potencialmente de manera diferente a la anterior).
- Si
- ese vive en después del comando.
Tenga en cuenta que cada variable de entorno también se expone como una variable de shell, pero no lo contrario. true: las variables de shell solo son visibles para el shell actual y sus subshells, pero no a procesos secundarios, como utilidades externas y scripts (sin origen) (a menos que estén marcados como variables de entorno con export
o declare -x
).
[1] Técnicamente, bash
está en violación de POSIX aquí (como es zsh
): Ya que eval
es un especial shell incorporado, el anterior NAME=sam
la asignación debe hacer que la variable $NAME
para permanecer en el alcance después de que finalice el comando, pero eso no es lo que sucede.
Sin embargo, cuando corres bash
en el modo de compatibilidad POSIX, es obediente.dash
y ksh
son siempre conformes.
Las reglas exactas son complicadas, y algunos aspectos se dejan a las implementaciones para decidir; de nuevo, consulte Búsqueda y ejecución de comandos.
Además, se aplica el descargo de responsabilidad habitual: Use eval
solo en la entrada que controla completamente o en la que confía implícitamente.
Esto también funciona con el punto y coma.
NAME=sam; echo $NAME