it-swarm.com.de

Definieren einer Variablen mit oder ohne Export

Wofür ist export?

Was ist der Unterschied zwischen:

export name=value

und

name=value
844
flybywire

export stellt die Variable Unterprozessen zur Verfügung.

Das ist,

export name=value

bedeutet, dass der Variablenname für jeden Prozess verfügbar ist, den Sie von diesem Shell-Prozess ausführen. Wenn ein Prozess diese Variable verwenden soll, verwenden Sie export und führen Sie den Prozess von dieser Shell aus.

name=value

bedeutet, dass der Gültigkeitsbereich der Variablen 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 beim Exportieren einer Variablen diese nicht für übergeordnete Prozesse verfügbar ist. Das heißt, das Angeben und Exportieren einer Variablen in einem erstellten Prozess macht sie in dem Prozess, der sie gestartet hat, nicht verfügbar.

938
Brian Agnew

Um zu veranschaulichen, was die anderen Antworten sagen:

$ foo="Hello, World"
$ echo $foo
Hello, World
$ bar="Goodbye"
$ export foo
$ bash
bash-3.2$ echo $foo
Hello, World
bash-3.2$ echo $bar

bash-3.2$ 
223
alxp

Andere haben geantwortet, dass export die Variable für Subshells verfügbar macht, und das ist richtig, aber nur ein Nebeneffekt. Wenn Sie eine Variable exportieren, wird diese in die Umgebung der aktuellen Shell gestellt (dh die Shell ruft putenv (3) oder setenv (3) auf). Die Umgebung eines Prozesses wird über exec vererbt, sodass die Variable in Subshells angezeigt wird.

Bearbeiten (mit 5-Jahres-Perspektive): Dies ist eine dumme Antwort. Der Zweck von 'Export' besteht darin, Variablen dazu zu bringen, "sich in der Umgebung von nachfolgend ausgeführten Befehlen zu befinden", unabhängig davon, ob es sich bei diesen Befehlen um Subshells oder Subprozesse handelt. Eine naive Implementierung würde darin bestehen, die Variable einfach in die Umgebung der Shell zu stellen, aber dies würde es unmöglich machen, export -p zu implementieren.

67
William Pursell

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 (die von (), ``, $() oder Schleifen erstellt werden) und Subprozessen (Prozesse, die über den Namen aufgerufen werden, z. B. ein Literal bash erscheint in Ihrem Skript).

  • Unter Shells werden haben Zugriff auf alle Variablen des übergeordneten Elements, unabhängig von ihrem exportierten Status.
  • Unter Prozessen werden nur die exportierten Variablen angezeigt.

Gemeinsam ist diesen beiden Konstrukten, dass keine der beiden Variablen an die übergeordnete Shell zurückgegeben werden 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 werden fork () unmittelbar von exec () gefolgt, und deshalb scheint es so, als wäre fork () das Richtige, während exec () das Richtige ist. Sie können Befehle ausführen, ohne zuvor mit dem Befehl exec gegabelt () zu haben, und Prozesse, die mit dieser Methode gestartet wurden, 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 diesmal die Zeile parent: nicht angezeigt wird, da wir die übergeordnete Shell durch den Befehl exec ersetzt haben, sodass dieser Befehl nicht mehr ausgeführt werden kann.

56
Matyas Koszik

export NAME=value für Einstellungen und Variablen, die für einen Unterprozess von Bedeutung sind.

NAME=value für temporäre Variablen oder Schleifenvariablen, die für den aktuellen Shell-Prozess privat sind.

Im Detail markiert export den Variablennamen in der Umgebung, der 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 angezeigt:

    $ 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 Haupt-Shell:

    $ export B="Bob"; echo 'B="Banana"' | bash; echo $B
    Bob
    
  • Für den Export markierte Variablen haben beim Erstellen des Unterprozesses kopierte Werte:

    $ 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
    

So, jetzt sollte es so klar sein wie die Sommersonne! Vielen Dank an Brain Agnew, alexp und William Prusell.

28
Charles Merriam

export stellt die Variable allen Shells zur Verfügung, die von der aktuellen Shell aus gegabelt wurden.

10
John T

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> ausführen, um die Eigenschaft zu entfernen.

$ K=1
$ export K
$ K=2
$ bash -c 'echo ${K-unset}'
2
$ export -n K
$ bash -c 'echo ${K-unset}'
unset
9
Brian S. Wilson

Wie Sie vielleicht bereits wissen, können Prozesse unter UNIX eine Reihe von Umgebungsvariablen verwenden, 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 zu verwalten.

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 zum Zeitpunkt der Erstellung des untergeordneten Prozesses für die Erstellung einer Kopie aller "envars" verantwortlich.

Bash kann unter anderem seine Umgebungsvariablen auf Benutzerwunsch setzen. Dafür gibt es export.

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 diese Bash erstellen würde.

Mehr zu Environment in Bash

Eine andere Art von Variable in Bash ist die interne Variable. Da Bash nicht nur eine interaktive Shell ist, ist es in der Tat ein Skriptinterpreter, wie jeder andere Interpreter (z. B. Python), der in der Lage ist, seinen eigenen Variablensatz zu behalten. Es sollte erwähnt werden, dass Bash (im Gegensatz zu Python) nur Stringvariablen unterstützt.

Die Notation zum Definieren von Bash-Variablen lautet name=value. Diese Variablen bleiben in Bash und haben nichts mit Umgebungsvariablen zu tun, die vom Betriebssystem verwaltet werden.

Weitere Informationen zu Shell-Parameter (einschließlich Variablen)

Beachten Sie auch, dass laut Bash-Referenzhandbuch:

Die Umgebung für einen einfachen Befehl oder eine Funktion kann vorübergehend erweitert werden, indem Parameterzuweisungen vorangestellt werden, wie in Shell Parameters 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 Bash-Variablen-Notation (Name = Wert) wird verwendet, um lokale Variablen festzulegen, die nur für den aktuellen Bash-Prozess verfügbar sind
  • Die Bash-Variablen-Notation, die einem anderen Befehl vorangestellt wird, erstellt Umgebungsvariablen nur für den Bereich dieses Befehls.
7
progalgo

Die akzeptierte Antwort impliziert dies, aber ich möchte die Verbindung zu Shell-Builtins explizit machen:

Wie bereits erwähnt, stellt export eine Variable sowohl der Shell als auch den untergeordneten Elementen zur Verfügung. Wenn export nicht verwendet wird, ist die Variable nur in der Shell und nur in der Shell verfügbar. Builtins 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
5
flow2k

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 finden Sie unter:

3
soxie

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 werden leicht eine PDF-Version finden.

Sie befassen sich mit Shell-Variablen in Abschnitt 3.6 und konzentrieren sich auf die Verwendung des Befehls export am Ende dieses Abschnitts:

Wenn Sie den Wert einer Variablen in Sub-Shells verfügbar machen möchten, sollten Sie den Export-Befehl der Shell verwenden. (Vielleicht überlegen Sie, warum es nicht möglich ist, den Wert einer Variablen aus einer Sub-Shell in die übergeordnete Shell zu exportieren.).

3
Dan Carter

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 noch $ OURNAME im env. Die Variable $ MYNAME befindet sich nicht in der Umgebung.

$ env | grep NAME
OURNAME=Jim

die Variable $ MYNAME existiert jedoch in der Shell

$ echo $MYNAME
Fred
2
Will

Obwohl in der Diskussion nicht explizit erwähnt, ist es NICHT erforderlich, den Export zu verwenden, wenn eine Subshell aus der Bash-Innenseite erzeugt wird, da alle Variablen in den untergeordneten Prozess kopiert werden.

0
Scott

In einem Skript erstellte Variablen stehen standardmäßig nur der aktuellen Shell zur Verfügung. Untergeordnete Prozesse (Sub-Shells) haben keinen Zugriff auf Werte, die festgelegt oder geändert wurden. Damit untergeordnete Prozesse die Werte sehen können, muss der Befehl export verwendet werden.

0
Amjad