Wie bestimmen Sie, ob Shell-Variablen exportiert werden oder nicht?

12

Bei der Bourne-Shell-Familie haben alle Shell-Variablen Großbuchstaben. Das heißt, Sie können nicht erkennen, ob eine bestimmte Variable eine Umgebungsvariable ist oder nicht, indem Sie nur ihren Namen betrachten. Wie bestimmen Sie, welche Bourne-Shell-Variablen lokal sind (nur innerhalb der aktuellen Shell definiert)?

Schulterpolster
quelle
4
Bourne Shell oder Bourne-Again Shell? Können Sie auf eine Referenz für die Variable in Großbuchstaben verweisen?
Jeff Schaller
Wie können Sie in der Bourne-again-Shell feststellen, welche Bash-Variablen lokal sind, da alle Variablen in Großbuchstaben geschrieben sind?
Shoulderpadz
7
@Shoulderpadz Nichts hindert Sie daran, Variablen in Kleinbuchstaben zu erstellen.
Muru
1
Mit lokal meinen Sie Variablen, die nicht exportiert wurden?
Eliah Kagan
4
Die Unterscheidung, nach der Sie fragen, ist Shell-Variablen gegen Umgebungsvariablen, nicht global gegen lokal. Beachten Sie, dass es Shell-Variablen gibt, die keine Umgebungsvariablen sind (dh was Sie als "lokal" bezeichnen), und es gibt Umgebungsvariablen, die keine Shell-Variablen sind (die Umgebung kann Namen enthalten, die keine gültigen Shell-Bezeichner sind, und somit kann keine Variable sein).
Chepner

Antworten:

17

Wenn Sie sehen möchten, ob eine Variable exportiert wird oder nicht, verwenden Sie declare:

$ foo=a bar=b
$ export foo
$ declare -p foo bar
declare -x foo="a"
declare -- bar="b"
muru
quelle
26

Der tragbarste Weg ist export -p.

export -plistet exportierte Variablen auf. Dies ist normalerweise so declare -x, wenn Ihre Shell hat declare.

Derzeit verwendete Bourne-Shells sollten unterstützen export -p, wie es von POSIX gefordert wird :

Wenn -p angegeben wird, schreibt der Export die Namen und Werte aller exportierten Variablen im folgenden Format in die Standardausgabe:

"export %s=%s\n", <name>, <value>

wenn der Name gesetzt ist und:

"export %s\n", <name>

wenn der Name nicht gesetzt ist.

Der Standard erklärt weiter, dass der Wert der Variablen so angezeigt wird, dass sie normalerweise später auf der rechten Seite =einer Zuweisung verwendet werden kann. Dies bedeutet, dass es zitiert werden kann. Verschiedene Muscheln können sie unterschiedlich anzeigen, aber mit dem gleichen Effekt. export -pfunktioniert auch in Shells, die nicht declareeingebaut sind, wie Dash .

$ dash -c 'export -p | grep HOME='  # busybox sh and other ash give the same output.
export HOME='/home/ek'
$ posh -c 'export -p | grep HOME='  # ksh93, mksh, lksh, and others give the same output.
export HOME=/home/ek

Ich habe die Ausgabe aus Gründen der grepKompaktheit weitergeleitet, aber wenn Sie sie nicht filtern, erhalten Sie die vollständige Liste Ihrer exportierten Variablen. Aus Ihrer Frage geht hervor, dass Sie dies möglicherweise am nützlichsten finden.

Einige Shells, wie z. B. Bash, verwenden ein nicht standardmäßiges Format, sofern nicht ausdrücklich angewiesen wird, sich POSIX-konform zu verhalten. In Bash export -pgibt es die gleiche Ausgabe wie declare -xstandardmäßig.

$ bash -c 'export -p | grep HOME='
declare -x HOME="/home/ek"
$ bash -c 'POSIXLY_CORRECT= export -p | grep HOME='
export HOME="/home/ek"
$ bash -c 'set -o posix; export -p | grep HOME='
export HOME="/home/ek"
$ bash --posix -c 'export -p | grep HOME='
export HOME="/home/ek"
$ ln -s /bin/bash sh
$ ./sh -c 'export -p | grep HOME='  # Invoking bash as sh also puts it in POSIX mode.
export HOME="/home/ek"

Zsh zeigt ein nicht standardmäßiges Format, auch wenn die POSIX-Kompatibilität aktiviert ist:

$ zsh -c 'export -p | grep HOME='
typeset -x HOME=/home/ek
$ zsh -c 'emulate -R sh; export -p | grep HOME='
typeset -x HOME=/home/ek
$ ln -s /bin/zsh sh
$ ./sh -c 'export -p | grep HOME='
typeset -x HOME=/home/ek

In jedem Fall können Sie tragbare Darstellungen (die möglicherweise zitiert werden) extrahieren, indem Sie nach einem Wort suchen, gefolgt von =. Dies hängt nicht von vorherigen Wörtern in der Zeile ab, solange sie nicht unmittelbar vorangehen =, was sie nicht sollten. Beispielsweise:

% export -p | grep -oE '\w+=.*'
HOME=/home/ek
LANG=en_US.UTF-8
LESSCLOSE='/usr/bin/lesspipe %s %s'
....

Beachten Sie, dass nicht alle Einträge unbedingt haben =. Dies liegt daran, dass Variablen nicht gesetzt, sondern exportiert werden können. Diese Einträge werden durch den grepobigen Befehl herausgefiltert, der möglicherweise Ihren Wünschen entspricht oder nicht.

Die meiste Zeit, wollen Sie nur die Ausgabe kontrollieren und so werden Sie es egal , ob die Einträge durch vorausgeht export, declare -x, typeset -x, oder etwas anderes. Dann renn einfach export -p.

Ich habe diese Befehle unter Ubuntu 16.04 LTS mit offiziell verpackten Versionen jeder Shell getestet .

Eliah Kagan
quelle
0

Variablen, die NICHT exportiert werden, können aus der Ausgabe des declareBefehls in bash gesehen werden.

Variablen , die werden exportiert wird, kann vom Ausgang der zu sehen declare -xoder exportBefehl in bash.

S471
quelle