Antworten:
export
stellt die Variable für Unterprozesse zur Verfügung.
Das ist,
export name=value
bedeutet, dass der Variablenname für jeden Prozess verfügbar ist, den Sie über diesen Shell-Prozess ausführen. Wenn ein Prozess diese Variable verwenden soll, verwenden Sie export
den Prozess und führen Sie ihn über diese Shell aus.
name=value
bedeutet, dass der Variablenbereich auf die Shell beschränkt ist und keinem anderen Prozess zur Verfügung steht. Sie würden dies für (sagen wir) Schleifenvariablen, temporäre Variablen usw. verwenden.
Es ist wichtig zu beachten, dass das Exportieren einer Variablen diese nicht für übergeordnete Prozesse verfügbar macht. Das heißt, das Angeben und Exportieren einer Variablen in einem erzeugten Prozess macht sie in dem Prozess, der sie gestartet hat, nicht verfügbar.
name=value command
stellt die Variable im Unterprozess zur Verfügung command
.
Andere haben geantwortet, dass der Export die Variable für Subshells verfügbar macht, und das ist richtig, aber nur ein Nebeneffekt. Wenn Sie eine Variable exportieren, wird diese Variable in die Umgebung der aktuellen Shell eingefügt (dh die Shell ruft putenv(3)
oder auf setenv(3)
).
Die Umgebung eines Prozesses wird über exec hinweg vererbt, wodurch die Variable in Subshells sichtbar wird.
Bearbeiten (mit 5-Jahres-Perspektive): Dies ist eine dumme Antwort. Der Zweck von 'Export' besteht darin, Variablen "in der Umgebung von anschließend ausgeführten Befehlen zu sein", unabhängig davon, ob diese Befehle Unterschalen oder Unterprozesse sind. Eine naive Implementierung wäre, die Variable einfach in die Umgebung der Shell zu stellen, aber dies würde eine Implementierung unmöglich machen export -p
.
bash
Export wird die Variable zwar zur Umgebung der aktuellen Shell hinzugefügt, dies ist jedoch bei nicht der Fall dash
. Es scheint mir, dass das Hinzufügen der Variablen zur Umgebung der aktuellen Shell der einfachste Weg ist, die Semantik von zu implementieren export
, aber dieses Verhalten ist nicht vorgeschrieben.
dash
damit zu tun hat. Das Originalplakat fragte speziell nach bash
.
bash
, gilt aber gleichermaßen für jede Bourne-Shell-Variante. Zu spezifisch zu sein und Antworten zu geben, die nur für gelten, bash
ist ein großes Übel.
bash
ist die jQuery der Shell.
export makes the variable available to subshells, and that is correct
Dies ist eine sehr verwirrende Verwendung der Terminologie. Subshells müssen keine export
Variablen erben. Unterprozesse tun.
Es wurde gesagt, dass es nicht notwendig ist, in Bash zu exportieren, wenn Subshells erzeugt werden, während andere das genaue Gegenteil sagten. Es ist wichtig , den Unterschied zwischen Subshells zu beachten (diejenigen , die erstellt werden ()
, ``
, $()
oder Schleifen) und Teilprozesse (Prozesse , die mit Namen aufgerufen werden, zum Beispiel eines wörtlichen bash
in Ihrem Skript erscheinen).
Was diesen beiden Konstrukten gemeinsam ist, ist, dass keine der Variablen Variablen an die übergeordnete Shell zurückgeben kann.
$ 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 noch eine weitere Quelle der Verwirrung: Einige denken, dass "gegabelte" Unterprozesse diejenigen sind, die keine nicht exportierten Variablen sehen. Normalerweise folgt auf fork () s sofort exec () s, und deshalb scheint es so, als ob man nach fork () sucht, während es tatsächlich exec () ist. Sie können Befehle ausführen, ohne zuerst fork () mit dem exec
Befehl auszuführen , und Prozesse, die mit dieser Methode gestartet werden, haben auch 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 die parent:
Zeile diesmal nicht sehen , da wir die übergeordnete Shell durch den exec
Befehl ersetzt haben, sodass nichts mehr übrig ist, um diesen Befehl auszuführen.
&
) erstellt auch eine Subshell.
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 die var
(ohne ;
) Rücksicht auf den hervorgebrachten Unterprozess irgendwie aufgrund der Ursprungsschale nichts damit zu tun hat. echo $var
Gibt nichts aus, wenn es in der zweiten Zeile ausgeführt wird. Aber eine Linie var=asdf bash -c 'echo $var'; echo $var
gibt asdf\nasdf
.
export NAME=value
für Einstellungen und Variablen, die für einen Unterprozess von Bedeutung sind.
NAME=value
für temporäre oder Schleifenvariablen, die für den aktuellen Shell-Prozess privat sind.
Markiert detaillierter export
den Variablennamen in der Umgebung, die bei der Erstellung in einen Unterprozess und dessen Unterprozesse kopiert wird. Kein Name oder Wert wird jemals aus dem Unterprozess zurückkopiert.
Ein häufiger Fehler besteht darin, 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 die Haupt-Shell nicht:
$ export B="Bob"; echo 'B="Banana"' | bash; echo $B
Bob
Für den Export markierte Variablen haben Werte, die beim Erstellen des Unterprozesses kopiert werden:
$ export B="Bob"; echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash &
[1] 3306
$ B="Banana"; echo '(sleep 30; echo "Subprocess 2 has B=$B")' | bash
Subprocess 1 has B=Bob
Subprocess 2 has B=Banana
[1]+ Done echo '(sleep 30; echo "Subprocess 1 has B=$B")' | bash
Nur exportierte Variablen werden Teil der Umgebung ( man environ
):
$ ALICE="Alice"; export BOB="Bob"; env | grep "ALICE\|BOB"
BOB=Bob
Jetzt sollte es so klar sein wie die Sommersonne! Vielen Dank an Brain Agnew, Alexp und William Prusell.
Es ist zu beachten, dass Sie eine Variable exportieren und später den Wert ändern können. Der geänderte Wert der Variablen steht untergeordneten Prozessen zur Verfügung. Nachdem der Export für eine Variable festgelegt wurde, müssen Sie export -n <var>
die Eigenschaft entfernen.
$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset
Wie Sie vielleicht bereits wissen, ermöglicht UNIX Prozessen, eine Reihe von Umgebungsvariablen zu haben, bei denen es sich um Schlüssel / Wert-Paare handelt, wobei sowohl Schlüssel als auch Wert Zeichenfolgen sind. Das Betriebssystem ist dafür verantwortlich, diese Paare für jeden Prozess separat aufzubewahren.
Das Programm kann über diese UNIX-API auf seine Umgebungsvariablen zugreifen:
char *getenv(const char *name);
int setenv(const char *name, const char *value, int override);
int unsetenv(const char *name);
Prozesse erben auch Umgebungsvariablen von übergeordneten Prozessen. Das Betriebssystem ist dafür verantwortlich, eine Kopie aller "Envars" zu erstellen, wenn der untergeordnete Prozess erstellt wird.
Bash ist unter anderem in der Lage, seine Umgebungsvariablen auf Benutzeranforderung festzulegen. Dafür gibt export
es.
export
ist ein Bash-Befehl zum Festlegen der Umgebungsvariablen für Bash. Alle mit diesem Befehl festgelegten Variablen würden von allen Prozessen geerbt, die dieser Bash erstellen würde.
Mehr zur Umwelt in Bash
Eine andere Art von Variable in Bash ist die interne Variable. Da Bash nicht nur eine interaktive Shell ist, ist es tatsächlich ein Skriptinterpreter, wie jeder andere Interpreter (z. B. Python), der in der Lage ist, seine eigenen Variablen zu behalten. Es sollte erwähnt werden, dass Bash (im Gegensatz zu Python) nur String-Variablen unterstützt.
Notation zum Definieren von Bash-Variablen ist name=value
. Diese Variablen bleiben in Bash und haben nichts mit Umgebungsvariablen zu tun, die vom Betriebssystem verwaltet werden.
Weitere Informationen zu Shell-Parametern (einschließlich Variablen)
Erwähnenswert ist auch, dass laut Bash Referenzhandbuch:
Die Umgebung für einfache Befehle oder Funktionen kann vorübergehend erweitert werden, indem Parameterzuweisungen vorangestellt werden, wie unter Shell-Parameter beschrieben . Diese Zuweisungsanweisungen wirken sich nur auf die Umgebung aus, die von diesem Befehl angezeigt wird.
Um es zusammenzufassen:
export
wird verwendet, um Umgebungsvariablen im Betriebssystem festzulegen. Diese Variable steht allen untergeordneten Prozessen zur Verfügung, die vom aktuellen Bash-Prozess erstellt wurden.Die akzeptierte Antwort impliziert dies, aber ich möchte die Verbindung zu eingebauten Shell explizit machen:
Wie bereits erwähnt, export
wird eine Variable sowohl für die Shell als auch für untergeordnete Elemente verfügbar gemacht. Wenn export
es nicht verwendet wird, ist die Variable nur in der Shell verfügbar, und nur in die Shell eingebaute Variablen können darauf zugreifen.
Das ist,
tango=3
env | grep tango # prints nothing, since env is a child process
set | grep tango # prints tango=3 - "type set" shows `set` is a shell builtin
Hier ist noch ein weiteres Beispiel:
VARTEST="value of VARTEST"
#export VARTEST="value of VARTEST"
sudo env | grep -i vartest
sudo echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"
sudo bash -c 'echo ${SUDO_USER} ${SUDO_UID}:${SUDO_GID} "${VARTEST}"'
Nur mit export VARTEST ist der Wert von VARTEST in sudo bash -c '...' verfügbar!
Weitere Beispiele siehe:
bash-hackers.org/wiki/doku.php/scripting/processtree
Zwei der Entwickler von UNIX, Brian Kernighan und Rob Pike, erklären dies in ihrem Buch "The UNIX Programming Environment". Google für den Titel und Sie finden leicht eine PDF-Version.
Sie befassen sich mit Shell-Variablen in Abschnitt 3.6 und konzentrieren sich auf die Verwendung des export
Befehls am Ende dieses Abschnitts:
Wenn Sie den Wert einer Variablen in Sub-Shells zugänglich machen möchten, sollte der Exportbefehl der Shell verwendet werden. (Sie könnten darüber nachdenken, warum es keine Möglichkeit gibt, den Wert einer Variablen von einer Unter-Shell in die übergeordnete Variable zu exportieren.)
Nur um den Unterschied zwischen einer exportierten Variablen in der Umgebung (env) und einer nicht exportierten Variablen in der Umgebung zu zeigen:
Wenn ich das mache:
$ MYNAME=Fred
$ export OURNAME=Jim
dann erscheint nur $ OURNAME in der Umgebung. Die Variable $ MYNAME befindet sich nicht in der Umgebung.
$ env | grep NAME
OURNAME=Jim
Die Variable $ MYNAME ist jedoch in der Shell vorhanden
$ echo $MYNAME
Fred
Standardmäßig sind in einem Skript erstellte Variablen nur für die aktuelle Shell verfügbar. Untergeordnete Prozesse (Unter-Shells) haben keinen Zugriff auf Werte, die festgelegt oder geändert wurden. Damit untergeordnete Prozesse die Werte anzeigen können, muss der Befehl export verwendet werden.
Obwohl in der Diskussion nicht explizit erwähnt, ist es NICHT erforderlich, den Export zu verwenden, wenn eine Subshell aus Bash heraus erzeugt wird, da alle Variablen in den untergeordneten Prozess kopiert werden.
export name=value
nicht tragbar ist. Versuchen Sie, je nachdem, was genau Sie möchten,name=value; export name
eine tragbare Lösung.