Wenn Prozesse die Umgebung des übergeordneten Elements erben, warum müssen wir dann exportieren?


72

Ich habe hier gelesen , dass der Zweck von exportin einer Shell ist, die Variable für Unterprozesse verfügbar zu machen, die von der Shell aus gestartet wurden.

Ich habe jedoch auch hier und hier gelesen , dass "Prozesse ihre Umgebung von ihren Eltern erben (dem Prozess, der sie gestartet hat)".

Wenn dies der Fall ist, warum brauchen wir export? Was vermisse ich?

Sind Shell-Variablen standardmäßig nicht Teil der Umgebung? Was ist der Unterschied?

Antworten:


74

Ihre Annahme ist, dass sich Shell-Variablen in der Umgebung befinden . Das ist falsch. Der exportBefehl definiert, wie ein Name überhaupt in der Umgebung sein soll. Somit:

a=1 b=2
export b

Dies führt dazu, dass die aktuelle Shell weiß, dass sie $aauf 1 und $b2 erweitert wird, Unterprozesse jedoch nichts davon wissen, ada sie nicht Teil der Umgebung sind (auch nicht in der aktuellen Shell).

Einige nützliche Tools:

  • set: Nützlich zum Anzeigen der aktuellen Shell-Parameter, exportiert oder nicht
  • set -k: Legt zugewiesene Argumente in der Umgebung fest. Erwägenf() { set -k; env; }; f a=1
  • set -a: Weist die Shell an, einen beliebigen Namen für die Umgebung festzulegen. Wie exportvor jeder Aufgabe setzen. Nützlich für .envDateien, wie in set -a; . .env; set +a.
  • export: Weist die Shell an, der Umgebung einen Namen zu geben. Export und Zuordnung sind zwei völlig unterschiedliche Vorgänge.
  • env: envKann Ihnen als externer Befehl nur Informationen über die vererbte Umgebung geben und ist daher nützlich für die Überprüfung der Integrität.
  • env -i: Nützlich zum Löschen der Umgebung vor dem Starten eines Unterprozesses.

Alternativen zu export:

  1. name=val command # Zuweisung vor Befehl exportiert diesen Namen in den Befehl.
  2. declare/local -x name # Exportiert den Namen, besonders nützlich in Shell-Funktionen, wenn Sie vermeiden möchten, dass der Name außerhalb des Gültigkeitsbereichs liegt.
  3. set -a # Exportiert jede folgende Zuordnung.

3
set -kist so, dass man cmd ENVVAR=valueanstelle von verwenden kann ENVVAR=value cmd, dass es in Ihrem Beispiel nur funktioniert, wenn set -kes vor dem Aufrufen ausgeführt wurde f. Außerdem wird es heutzutage nicht mehr von vielen Shells unterstützt und nur aus Gründen der Abwärtskompatibilität mit der Bourne-Shell. In der Bourne- (oder Korn-) Shell würde das für Funktionen nicht funktionieren. Und da es die Shell-Analyse beeinflusst, muss es zu dem Zeitpunkt in Kraft sein, an dem die Shell den Code liest , der ihn dort verwendet.
Stéphane Chazelas

1
Vielleicht möchten Sie auch erwähnenset -a
Stéphane Chazelas

24

Es gibt einen Unterschied zwischen Shell-Variablen und Umgebungsvariablen. Wenn Sie eine Shell-Variable definieren, ohne exportsie zu definieren, wird sie nicht zur Prozessumgebung hinzugefügt und somit nicht an ihre untergeordneten Elemente vererbt.

Mit weisen exportSie die Shell an, die Shell-Variable der Umgebung hinzuzufügen. Sie können dies mit testen printenv(wobei nur die Umgebung gedruckt wird stdout, da dies ein untergeordneter Prozess ist, bei dem Sie die Auswirkung von exportVariablen sehen):

#!/bin/sh

MYVAR="my cool variable"

echo "Without export:"
printenv | grep MYVAR

echo "With export:"
export MYVAR
printenv | grep MYVAR

6

Eine einmal exportierte Variable ist Teil der Umgebung. PATHwird in der Shell selbst exportiert, während benutzerdefinierte Variablen nach Bedarf exportiert werden können. Verwenden Sie einen Setup-Code:

$ cat subshell.sh 
#!/usr/bin/env bash
declare | grep -e '^PATH=' -e '^foo='

Vergleichen Sie

$ cat test.sh 
#!/usr/bin/env bash
export PATH=/bin
export foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test.sh 
PATH=/bin
foo=bar
PATH=/bin
foo=bar

Mit

$ cat test2.sh 
#!/usr/bin/env bash
PATH=/bin
foo=bar
declare | grep -e '^PATH=' -e '^foo='
./subshell.sh
$ ./test2.sh 
PATH=/bin
foo=bar
PATH=/bin

Da fooes von der Shell nicht exportiert und test2.shnie exportiert wird, war es subshell.shim letzten Durchlauf nicht Teil der Umgebung von .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.