Son alcanzados por proceso
Los otros respondedores me ayudaron a comprender que el alcance variable de shell se trata de procesos y sus descendientes .
Cuando escribe un comando como ls
en la línea de comando, en realidad está bifurcando un proceso para ejecutar el ls
programa. El nuevo proceso tiene su shell como padre.
Cualquier proceso puede tener sus propias variables "locales", que no se pasan a los procesos secundarios. También puede establecer variables de "entorno", que son. El uso export
crea una variable de entorno. En cualquier caso, los procesos no relacionados (pares del original) no verán la variable; solo estamos controlando lo que ven los procesos secundarios.
Supongamos que tiene un shell bash, al que llamaremos A. Usted escribe bash
, lo que crea un shell bash de proceso hijo, al que llamaremos B. Cualquier cosa que haya llamado export
en A todavía se establecerá en B.
Ahora, en B, dices FOO=b
. Sucederá una de dos cosas:
- Si B no recibió (de A) una variable de entorno llamada
FOO
, creará una variable local. Los niños de B no lo recibirán (a menos que B llame export
).
- Si B no recibir (de A) una variable de entorno callled
FOO
, se modificarlo para sí y sus hijos posteriormente bifurcadas . Los hijos de B verán el valor que B asignó. Sin embargo, esto no afectará a A en absoluto.
Aquí hay una demostración rápida.
FOO=a # set "local" environment variable
echo $FOO # 'a'
bash # forks a child process for the new shell
echo $FOO # not set
exit # return to original shell
echo $FOO # still 'a'
export FOO # make FOO an environment variable
bash # fork a new "child" shell
echo $FOO # outputs 'a'
FOO=b # modifies environment (not local) variable
bash # fork "grandchild" shell
echo $FOO # outputs 'b'
exit # back to child shell
exit # back to original shell
echo $FOO # outputs 'a'
Todo esto explica mi problema original: configuré GEM_HOME
mi shell, pero cuando llamé bundle install
, eso creó un proceso secundario. Como no lo había usado export
, el proceso hijo no recibió el shell GEM_HOME
.
No exportar
Puede "desexportar" una variable, evitando que se pase a los niños, mediante el uso export -n FOO
.
export FOO=a # Set environment variable
bash # fork a shell
echo $FOO # outputs 'a'
export -n FOO # remove environment var for children
bash # fork a shell
echo $FOO # Not set
exit # back up a level
echo $FOO # outputs 'a' - still a local variable
FOO=bar
, eso establece el valor para el proceso actual del shell. Si luego ejecuto un programa como (bundle install
), eso crea un proceso secundario, al que no tiene accesoFOO
. Pero si hubiera dichoexport FOO=bar
, el proceso hijo (y sus descendientes) tendrían acceso a él. Uno de ellos podría, a su vez, llamarexport FOO=buzz
para cambiar el valor de sus descendientes, o simplementeFOO=buzz
para cambiar el valor solo para sí mismo. ¿Eso es correcto?