Esto se reduce a una cuestión de cómo funciona la evaluación. Ambos ejemplos funcionan de la misma manera, el problema ocurre debido a cómo el shell (bash, aquí) expande las variables.
Cuando escribes este comando:
HOME="foo" echo $HOME
El $HOME
se expande antes de ejecutar el comando . Por lo tanto, se expande al valor original y no al nuevo en el que lo configuró para el comando. De hecho, la HOME
variable se ha cambiado en el entorno en el que echo
se ejecuta el comando, sin embargo, está imprimiendo $HOME
desde el padre.
Para ilustrar, considere esto:
$ HOME="foo" bash -c 'echo $HOME'
foo
$ echo $HOME
/home/terdon
Como puede ver arriba, el primer comando imprime el valor modificado temporalmente HOME
y el segundo imprime el original, lo que demuestra que la variable solo se modificó temporalmente. Debido a que el bash -c ...
comando está encerrado entre comillas simples ( ' '
) en lugar de comillas dobles ( " "
), la variable no se expande y se pasa como está al nuevo proceso bash. Este nuevo proceso luego lo expande e imprime el nuevo valor en el que se ha establecido. Puede ver que esto suceda si usa set -x
:
$ set -x
$ HOME="hello" echo "$HOME"
+ HOME=hello
+ echo hello
hello
Como puede ver arriba, la variable $HOME
nunca se pasa a echo
. Solo ve su valor expandido. Comparar con:
$ HOME="hello" bash -c 'echo $HOME'
+ HOME=hello
+ bash -c 'echo $HOME'
hello
Aquí, debido a las comillas simples, la variable y no su valor se pasan al nuevo proceso.
local
.eval
evitar la solución?Hay dos ámbitos: variables de entorno y variables locales. Las variables de entorno son válidas para cada proceso (ver
setenv
,getenv
), mientras que las variables locales están activas solo dentro de esta sesión de shell. (No es una distinción obvia ...)Implícito
env
(como en su ejemplo) modifica el entorno, mientrasecho ...
usa los locales, por lo queenv
no tiene ningún efecto.Para modificar el uso de variables locales, digamos,
Aquí los paréntesis definen el alcance de esta asignación.
fuente