Tangential beachten Sie auch, dass export name=valuenicht tragbar ist. Versuchen Sie, je nachdem, was genau Sie möchten, name=value; export nameeine tragbare Lösung.
Tripleee
Antworten:
1054
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 exportden 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.
Insbesondere exportiert export die Variable untergeordneten Prozessen über die Umgebung zur Verfügung.
Beano
15
Ich würde auch hinzufügen, dass wenn der Export in einer Datei ist, die Sie "quellen" (wie. Dateiname), es ihn auch in Ihre Arbeitsumgebung exportiert.
Rogerdpack
6
@rogerdpack kannst du das nicht ohne export machen? cat> blah \ na = hi \ n. bla; echo $ a; gibt 'hi' für mich aus.
David Winiecki
2
Schön, dass es auch ohne Export funktioniert. Ich denke also, wenn Sie eine Datei beschaffen, wenn Sie den Export verwenden, wird dies in
untergeordneten
19
Es gibt einen Randfall dazu; name=value commandstellt die Variable im Unterprozess zur Verfügung command.
Oliver Charlesworth
254
Um zu veranschaulichen, was die anderen Antworten sagen:
Ein weiteres Beispiel dafüral$ foobar="Whatever" bash
Alun
70
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.
Beachten Sie, dass dies nicht ganz stimmt. Beim bashExport 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.
William Pursell
7
Ich bin mir nicht sicher, was dashdamit zu tun hat. Das Originalplakat fragte speziell nach bash.
Seestern
14
Die Frage ist markiert bash, gilt aber gleichermaßen für jede Bourne-Shell-Variante. Zu spezifisch zu sein und Antworten zu geben, die nur für gelten, bashist ein großes Übel.
William Pursell
12
bashist die jQuery der Shell.
Potherca
2
export makes the variable available to subshells, and that is correctDies ist eine sehr verwirrende Verwendung der Terminologie. Subshells müssen keine exportVariablen erben. Unterprozesse tun.
Amit Naidu
62
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 bashin Ihrem Skript erscheinen).
Unterschalenwird Zugriff auf alle Variablen aus dem Elternteil haben, unabhängig von ihrer exportierten Zustand.
Sub - Prozesse werden nur die exportierten Variablen sehen.
Was diesen beiden Konstrukten gemeinsam ist, ist, dass keine der Variablen Variablen an die übergeordnete Shell zurückgeben kann.
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 execBefehl auszuführen , und Prozesse, die mit dieser Methode gestartet werden, haben auch keinen Zugriff auf nicht exportierte Variablen:
Beachten Sie, dass wir die parent:Zeile diesmal nicht sehen , da wir die übergeordnete Shell durch den execBefehl ersetzt haben, sodass nichts mehr übrig ist, um diesen Befehl auszuführen.
Ich habe noch nie eine Schleife gesehen, die (für sich) eine Unterschale erstellt hat. OTOH eine Pipeline (immer für andere Teile als die letzten, manchmal für die letzten, abhängig von Ihrer Shell, Version und Optionen). Backgrounding ( &) erstellt auch eine Subshell.
dave_thompson_085
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 die var(ohne ;) Rücksicht auf den hervorgebrachten Unterprozess irgendwie aufgrund der Ursprungsschale nichts damit zu tun hat. echo $varGibt nichts aus, wenn es in der zweiten Zeile ausgeführt wird. Aber eine Linie var=asdf bash -c 'echo $var'; echo $vargibt asdf\nasdf.
4xy
31
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 exportden 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
Subprocess1 has B=BobSubprocess2 has B=Banana[1]+Done echo '(sleep 30; echo "Subprocess 1 has B=$B")'| bash
Nur exportierte Variablen werden Teil der Umgebung ( man environ):
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.
Vielen Dank, dies sind genau die Informationen, nach denen ich gesucht habe, da ich ein Skript gesehen habe, das Umgebungsvariablen verwendet und diese dann mit einem neuen Wert "erneut exportiert" hat, und mich gefragt habe, ob dies erforderlich ist.
Mike Lippert
8
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 exportes.
exportist 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.
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.
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:
exportwird verwendet, um Umgebungsvariablen im Betriebssystem festzulegen. Diese Variable steht allen untergeordneten Prozessen zur Verfügung, die vom aktuellen Bash-Prozess erstellt wurden.
Die Bash-Variablennotation (Name = Wert) wird verwendet, um lokale Variablen festzulegen, die nur für den aktuellen Bash-Prozess verfügbar sind
Die Bash-Variablennotation, die einem anderen Befehl vorangestellt ist, erstellt eine Umgebungsvariable nur für den Umfang dieses Befehls.
Bash-Vars unterstützen nicht so viele Typen wie Python, haben jedoch String, Integer und zwei Arten von Arrays ('indiziert' / traditionell und 'assoziativ', ähnlich wie awk-Array, Perl-Hash oder Python-Diktat). Andere Muscheln variieren; Nur String ist portabel .
Dave_thompson_085
7
Die akzeptierte Antwort impliziert dies, aber ich möchte die Verbindung zu eingebauten Shell explizit machen:
Wie bereits erwähnt, exportwird eine Variable sowohl für die Shell als auch für untergeordnete Elemente verfügbar gemacht. Wenn exportes 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 processset| grep tango # prints tango=3 - "type set" shows `set` is a shell builtin
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 exportBefehls 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.)
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.
Bitte erläutern Sie, wie das, was Sie sagen, den Antworten mit den obigen Beispielen direkt zu widersprechen scheint.
Mike Lippert
Dies ist der richtige Weg, wenn Sie nicht möchten, dass die Variablen global exportiert werden, sondern nur für den Unterprozess verfügbar sind! Vielen Dank.
export name=value
nicht tragbar ist. Versuchen Sie, je nachdem, was genau Sie möchten,name=value; export name
eine tragbare Lösung.Antworten:
export
stellt die Variable für Unterprozesse zur Verfügung.Das ist,
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.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.
quelle
name=value command
stellt die Variable im Unterprozess zur Verfügungcommand
.Um zu veranschaulichen, was die anderen Antworten sagen:
quelle
al$ foobar="Whatever" bash
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 aufsetenv(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
.quelle
bash
Export wird die Variable zwar zur Umgebung der aktuellen Shell hinzugefügt, dies ist jedoch bei nicht der Falldash
. Es scheint mir, dass das Hinzufügen der Variablen zur Umgebung der aktuellen Shell der einfachste Weg ist, die Semantik von zu implementierenexport
, aber dieses Verhalten ist nicht vorgeschrieben.dash
damit zu tun hat. Das Originalplakat fragte speziell nachbash
.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 keineexport
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örtlichenbash
in Ihrem Skript erscheinen).Was diesen beiden Konstrukten gemeinsam ist, ist, dass keine der Variablen Variablen an die übergeordnete Shell zurückgeben kann.
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:Beachten Sie, dass wir die
parent:
Zeile diesmal nicht sehen , da wir die übergeordnete Shell durch denexec
Befehl ersetzt haben, sodass nichts mehr übrig ist, um diesen Befehl auszuführen.quelle
&
) erstellt auch eine Subshell.var=asdf bash -c 'echo $var'
odervar=asdf exec bash -c 'echo $var'
? Die Ausgabe istasdf
. Das;
macht einen Unterschied, wenn es nach der Variablendefinition platziert wird. Was wäre die Erklärung? Es sieht so aus, als ob dievar
(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 Linievar=asdf bash -c 'echo $var'; echo $var
gibtasdf\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:
Nur die exportierte Variable (
B
) wird vom Unterprozess gesehen:Änderungen im Unterprozess ändern die Haupt-Shell nicht:
Für den Export markierte Variablen haben Werte, die beim Erstellen des Unterprozesses kopiert werden:
Nur exportierte Variablen werden Teil der Umgebung (
man environ
):Jetzt sollte es so klar sein wie die Sommersonne! Vielen Dank an Brain Agnew, Alexp und William Prusell.
quelle
export
stellt die Variable allen Shells zur Verfügung, die von der aktuellen Shell gegabelt wurden.quelle
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.quelle
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:
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.quelle
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. Wennexport
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,
quelle
Hier ist noch ein weiteres Beispiel:
Nur mit export VARTEST ist der Wert von VARTEST in sudo bash -c '...' verfügbar!
Weitere Beispiele siehe:
http://mywiki.wooledge.org/SubShell
bash-hackers.org/wiki/doku.php/scripting/processtree
quelle
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:quelle
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:
dann erscheint nur $ OURNAME in der Umgebung. Die Variable $ MYNAME befindet sich nicht in der Umgebung.
Die Variable $ MYNAME ist jedoch in der Shell vorhanden
quelle
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.
quelle
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.
quelle