Sie sind prozessbezogen
Die anderen Antworten haben mir geholfen zu verstehen, dass es bei dem Shell-Variablenbereich um Prozesse und deren Nachkommen geht .
Wenn Sie einen Befehl wie ls
in der Befehlszeile eingeben, veranlassen Sie einen Prozess, das ls
Programm auszuführen . Der neue Prozess hat Ihre Shell als übergeordnetes Element.
Jeder Prozess kann seine eigenen "lokalen" Variablen haben, die nicht an untergeordnete Prozesse übergeben werden. Es können auch Umgebungsvariablen gesetzt werden. Mit export
wird eine Umgebungsvariable erstellt. In beiden Fällen wird die Variable für nicht verwandte Prozesse (Peers des Originals) nicht angezeigt. Wir steuern nur, was untergeordnete Prozesse sehen.
Angenommen, Sie haben eine Bash-Shell, die wir A nennen. Sie geben ein bash
, wodurch eine untergeordnete Prozess-Bash-Shell erstellt wird, die wir B nennen. Alles, was Sie export
in A aufgerufen haben, wird weiterhin in B gesetzt.
Nun, in B, sagst du FOO=b
. Eines von zwei Dingen wird passieren:
- Wenn B keine aufgerufene Umgebungsvariable (von A) erhalten hat
FOO
, wird eine lokale Variable erstellt. Kinder von B werden es nicht bekommen (außer B ruft an export
).
- Wenn B haben (von A) erhalten eine Umgebungsvariable callled
FOO
, wird sie es für sich selbst verändern und ihre anschließend gegabelt Kinder . Kindern von B wird der von B zugewiesene Wert angezeigt. Dies hat jedoch keinerlei Auswirkungen auf A.
Hier ist eine kurze Demo.
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'
All dies erklärt mein ursprüngliches Problem: Ich habe GEM_HOME
in meiner Shell festgelegt, aber als ich anrief bundle install
, wurde ein untergeordneter Prozess erstellt. Da ich nicht verwendet hatte export
, hat der untergeordnete Prozess die Shell nicht erhalten GEM_HOME
.
Export wird abgebrochen
Sie können eine Variable "dekomprimieren" - verhindern, dass sie an untergeordnete Variablen übergeben wird -, indem Sie verwenden 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
, legt dies den Wert für den aktuellen Shell-Prozess fest. Wenn ich dann ein Programm wie (bundle install
) ausführe , wird ein untergeordneter Prozess erstellt, auf den nicht zugegriffen werden kannFOO
. Aber wenn ich gesagt hatteexport FOO=bar
, das Kind Prozess (und deren Nachkommen) würde den Zugang zu ihm haben. Einer von ihnen könnte wiederum anrufenexport FOO=buzz
, um den Wert für seine NachkommenFOO=buzz
zu ändern , oder nur , um den Wert nur für sich selbst zu ändern. Ist das ungefähr richtig?