Mein Problem besteht darin, dass ich beim Beginn der Codierung meines Skripts auf mehrere Probleme mit dem Variablenbereich gestoßen bin, die zu der schlechten Angewohnheit geführt haben, fast alle meine Variablen zu exportieren.
Da mein Code nun ziemlich groß geworden ist, habe ich überlegt, ihn zu bereinigen, und dazu gehört auch das Entfernen einer Reihe nutzloser Exporte. Leider bin ich mir nicht sicher, ob mein Wissen über den Variablenbereich vollständig ist. Selbst nachdem ich einige Seiten zu diesem Thema gelesen habe.
Was ich weiß (und hoffentlich richtig ist):
1-Durch das Exportieren einer Variablen wird ihr Inhalt für Subshell-Prozesse verfügbar:
export myvar="content"
2-Auf Dinge, die in Klammern wie diesen stehen, wirkt sich das Entfernen von Exporten aus (soweit ich weiß, ist dies die einzige Möglichkeit, eine Untershell zu deklarieren/verwenden):
$(grep "content" <<< $myvar)
3-Variablen, die ohne Festlegen ihres Gültigkeitsbereichs deklariert werden, sind global:
myvar="content"
4-Da ich keine lokalen Variablen deklariere, muss ich mir keine Sorgen machen, dass innerhalb meiner Funktionen Probleme entstehen:
local myvar="i don't use this"
Fragen:
1- Hat es irgendeinen Sinn, mit dem Entfernen der nutzlosen Exporte fortzufahren, wenn mein Code nicht offensichtlich nach Anfängerwissen riecht?
2- Wenn ich damit fortfahre, gibt es sonst noch etwas, das ich beachten sollte, das betroffen sein und meinen Code beschädigen könnte? Oder sind meine Kenntnisse falsch/unvollständig?
3- Wenn Sie eine gut geschriebene (und vollständige) Referenz zum variablen Gültigkeitsbereich kennen, geben Sie bitte den Link weiter.
Antwort1
Sie können alle Exporte entfernen, ohne dass dies Auswirkungen auf die exportierten Variablen hat, solange Sie nicht export
zweimal auswerten. Mit zweimal auswerten meine ich:
var1=var2
export "${var1}=var3"
echo "$var2"
var3
Verwenden Sie stattdessen einfach:
set -a
...am Anfang des Skripts. Alle danach definierten Variablen werden automatisch festgelegt exported
– einschließlich Variablen, die Sie möglicherweise vorher nicht export
festgelegt haben. Alternativ können Sie nur set -a
einen Teil des Skripts festlegen und set +a
ihn später löschen – es könnte auch als Funktion funktionieren.
Aber Subshells erben Variablenwerte sowieso automatisch, also:
var1=value
( echo "$(echo "$var1")" )
value
export
macht in diesem Fall keinen Unterschied.
Wenn Ihr Skript jedoch ein anderes Skript oder eine andere ausführbare Datei aufruft, die die von Ihnen eingegebenen Werte interpretiert, export
und Sie diese beenden export
, sind diese Werte in ihrer Umgebung nicht mehr verfügbar. Im folgenden Beispiel verwende ich die Shell-Variable $PS1
, die den Inhalt der Eingabeaufforderung einer interaktiven Shell definiert, um zu demonstrieren, wie sich Variationen der export
eingegebenen Variablen auf untergeordnete Prozesse auswirken.
export PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i
###OUTPUT###
this is another executable
> exit
exit
Aber ...
PS1="$(printf "this is another executable\n > ")"
echo exit | sh -i
###OUTPUT###
sh-4.3$ exit
exit
Wenn Sie jedoch beim Aufrufen eines Prozesses Umgebungsvariablen explizit deklarieren ...
PS1="$(printf "this is another executable\n > ")"
{
echo exit | PS1=$PS1 sh -i
echo exit | sh -i
}
###OUTPUT###
this is another executable
> exit
exit
sh-4.3$ exit
exit