Wofür ist export
?
Was ist der Unterschied zwischen:
export name=value
und
name=value
Wofür ist export
?
Was ist der Unterschied zwischen:
export name=value
und
name=value
export
stellt die Variable sub-Prozessen zur Verfügung.
Das bedeutet,
export name=value
bedeutet, dass die Variable name für jeden Prozess verfügbar ist, den Sie von diesem Shell-Prozess ausführen. Wenn Sie möchten, dass ein Prozess diese Variable verwendet, verwenden Sie export
und führen Sie den Prozess von dieser Shell aus.
name=value
bedeutet, dass der Geltungsbereich der Variable auf die Shell beschränkt ist und für keinen anderen Prozess verfügbar ist. Sie würden dies für (zum Beispiel) Schleifenvariablen, temporäre Variablen usw. verwenden.
Es ist wichtig zu beachten, dass das Exportieren einer Variable diese nicht für übergeordnete Prozesse verfügbar macht. Das bedeutet, dass das Angeben und Exportieren einer Variable in einem abgeleiteten Prozess sie nicht im Prozess verfügbar macht, der ihn gestartet hat.
Ich würde auch hinzufügen, dass wenn der Export in einer Datei erfolgt, die Sie "sourcen" (wie z.B. . Dateiname), dann wird er auch in Ihre Arbeitsumgebung exportiert.
@rogerdpack kannst du das ohne Export machen? cat > blah \n a=hi \n . blah; echo $a; gibt 'hi' für mich aus.
Nur für den Fall, dass jemand dies in Bash mit Arrays ausprobieren möchte (wie ich es getan habe...), hier ein Hinweis: es geht nicht.
Es wurde gesagt, dass es nicht notwendig ist, in Bash zu exportieren, wenn Unterprozesse gestartet werden, während andere genau das Gegenteil behaupten. Es ist wichtig, den Unterschied zwischen Unterprozessen (die durch ()
, ``
, $()
oder Schleifen erstellt werden) und Teilprozessen (Prozesse, die durch Namen aufgerufen werden, zum Beispiel ein wörtliches bash
in Ihrem Skript) zu beachten.
Was in diesen beiden Konstrukten gemeinsam ist, ist, dass weder Variablen an den übergeordneten Shellprozess zurückgegeben werden können.
$ noexport=noexport; export export=export; (echo subshell: $noexport $export; subshell=subshell); bash -c 'echo subprocess: $noexport $export; subprocess=subprocess'; echo parent: $subshell $subprocess
subshell: noexport export
subprocess: export
parent:
Es gibt eine weitere Quelle der Verwirrung: Manche glauben, dass 'geforkte' Teilprozesse diejenigen sind, die nicht auf nicht exportierte Variablen zugreifen können. Normalerweise werden fork()s sofort von exec()s gefolgt, und deshalb scheint es, dass man nach dem fork() suchen muss, während es in Wirklichkeit das exec() ist. Sie können Befehle ohne vorheriges Forking mit dem Befehl exec
ausführen, und Prozesse, die auf diese Weise gestartet werden, haben ebenfalls keinen Zugriff auf nicht exportierte Variablen:
$ noexport=noexport; export export=export; exec bash -c 'echo execd process: $noexport $export; execd=execd'; echo parent: $execd
execd process: export
Beachten Sie, dass wir dieses Mal die parent:
Zeile nicht sehen, da wir die übergeordnete Shell durch den exec
Befehl ersetzt haben, sodass nichts übrig bleibt, um diesen Befehl auszuführen.
Ich habe noch nie eine Schleife gesehen, die (von selbst) eine Unter-Shell erstellt hat; andererseits erstellt eine Pipeline (immer für Teile außer dem letzten, manchmal für den letzten abhängig von Ihrer Shell, Version und Optionen) eine Unter-Shell. Das Hintergrundsetzen (&
) erstellt ebenfalls eine Unter-Shell.
Was ist mit diesen var=asdf bash -c 'echo $var'
oder var=asdf exec bash -c 'echo $var'
? Die Ausgabe ist asdf
. Das ;
macht einen Unterschied, wenn es nach der Variablendefinition platziert wird. Was wäre die Erklärung? Es sieht so aus, als ob das var
(ohne ;
) sich irgendwie auf den gestarteten Prozess bezieht, da die Ursprungsshell nichts damit zu tun hat. echo $var
gibt nichts aus, wenn es in der zweiten Zeile ausgeführt wird. Aber in einer Zeile var=asdf bash -c 'echo $var'; echo $var
ergibt asdf\nasdf
.
Dies ist eine falsche Antwort, die jedoch aus historischen Gründen beibehalten wurde. Siehe unten die 2. Bearbeitung.
Andere haben geantwortet, dass export die Variable für Unter-Shell verfügbar macht, und das ist korrekt, aber nur ein Nebeneffekt. Wenn Sie eine Variable exportieren, platziert sie diese Variable in die Umgebung der aktuellen Shell (d. h. die Shell ruft putenv(3)
oder setenv(3)
auf).
Die Umgebung eines Prozesses wird bei exec vererbt, wodurch die Variable in Unter-Shell sichtbar wird.
Bearbeitung (mit 5 Jahren Perspektive): Dies ist eine alberne Antwort. Der Zweck von 'export' besteht darin, Variablen "in der Umgebung von anschließend ausgeführten Befehlen zu sein", ob diese Befehle Unter-Shell oder Unterprozesse sind. Eine naive Implementierung wäre es, die Variable einfach in die Umgebung der Shell zu setzen, aber dadurch wäre es unmöglich, export -p
zu implementieren.
2. Bearbeitung (weitere 5 Jahre sind vergangen). Diese Antwort ist einfach bizarr. Möglicherweise hatte ich irgendwann einen Grund zu behaupten, dass bash die exportierte Variable in ihre eigene Umgebung setzt, aber diese Gründe wurden hier nicht angegeben und sind jetzt verloren gegangen. Siehe Exportieren einer funktionslokalen Variable in die Umgebung.
Bitte beachten Sie, dass dies nicht ganz korrekt ist. In bash
fügt export die Variable tatsächlich zur Umgebung der aktuellen Shell hinzu, aber das ist bei dash
nicht der Fall. Es scheint mir, dass das Hinzufügen der Variable zur Umgebung der aktuellen Shell der einfachste Weg ist, um die Semantik von export
zu implementieren, aber dieses Verhalten ist nicht vorgeschrieben.
Ich bin mir nicht sicher, was dash
damit zu tun hat. Der Original-Poster hat speziell nach bash
gefragt.
Die Frage ist mit bash
getaggt, gilt jedoch gleichermaßen für jede Bourne-Shell-Variante. Es ist sehr schlimm, übermäßig spezifisch zu sein und Antworten zu geben, die nur für bash
gelten.
export NAME=value
für Einstellungen und Variablen, die für einen Unterprozess eine Bedeutung haben.
NAME=value
für temporäre oder Schleifenvariablen, die privat für den aktuellen Shell-Prozess sind.
Im Detail markiert export
den Variablennamen in der Umgebung, der in Unterprozessen und deren Unterprozessen beim Erstellen kopiert wird. Es wird nie ein Name oder Wert aus dem Unterprozess zurückkopiert.
Ein häufiger Fehler ist es, ein Leerzeichen um das Gleichheitszeichen zu setzen:
$ export FOO = "bar"
bash: export: `=': not a valid identifier
Nur die exportierte Variable (B
) wird vom Unterprozess gesehen:
$ A="Alice"; export B="Bob"; echo "echo A is \$A. B is \$B" | bash
A is . B is Bob
Änderungen im Unterprozess ändern nicht die Hauptshell:
$ export B="Bob"; echo 'B="Banana"' | bash; echo $B
Bob
Markierte Variablen für den Export haben Werte, die beim Erstellen des Unterprozesses kopiert werden:
$ export B="Bob"; echo '(sleep 30; echo "Subprozess 1 hat B=$B")' | bash &
[1] 3306
$ B="Banana"; echo '(sleep 30; echo "Subprozess 2 hat B=$B")' | bash
Subprozess 1 hat B=Bob
Subprozess 2 hat B=Banana
[1]+ Done echo '(sleep 30; echo "Subprozess 1 hat B=$B")' | bash
Nur exportierte Variablen werden Teil der Umgebung (man environ
):
$ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB"
BOB=Bob
Also, jetzt sollte klar sein wie die Sonne im Sommer! Danke an Brain Agnew, alexp und William Prusell.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
2 Stimmen
Siehe auch: stackoverflow.com/questions/68529921/…