Ich wusste eigentlich nicht, dass es zwei verschiedene Arten von Variablen gibt, auf die ich über die Befehlszeile zugreifen kann. Ich wusste nur, dass ich Variablen deklarieren kann wie:
foo="my dear friends"
bar[0]="one"
bar[1]="two"
bar[2]="three"
oder mit einem $ -Zeichen darauf zugreifen, wie:
echo $foo
echo ${bar[1]}
oder mit eingebauten Variablen, wie:
echo $PWD
PATH=$PATH:"/usr/bin/myProg"
Jetzt höre ich, dass es zwei (mindestens?) Arten von Variablen gibt: Shell-Variablen und Umgebungsvariablen.
- Was ist der Zweck von zwei verschiedenen Typen?
- Woher weiß ich, welcher Typ eine Variable ist?
- Was sind die typischen Verwendungen für jeden?
Antworten:
Umgebungsvariablen sind eine Liste von
name=value
Paaren, die unabhängig vom Programm existieren (Shell, Anwendung, Daemon…). Sie werden normalerweise von untergeordneten Prozessen geerbt (erstellt vonfork
/exec
sequence): Untergeordnete Prozesse erhalten eine eigene Kopie der übergeordneten Variablen.Shell-Variablen existieren nur im Kontext einer Shell. Sie werden nur in Subshells vererbt (dh wenn die Shell ohne
exec
Operation gegabelt wird ). Abhängig von den Shell-Funktionen können Variablen nicht nur einfache Zeichenfolgen wie Umgebungszeichenfolgen sein, sondern auch Arrays, zusammengesetzte, typisierte Variablen wie Ganzzahlen oder Gleitkommazahlen usw.Wenn eine Shell gestartet wird, werden alle von ihr
IFS
geerbten Umgebungsvariablen zu Shellvariablen (es sei denn, sie sind als Shellvariablen und andere Eckfälle, wie sie von einigen Shells zurückgesetzt werden, ungültig ). Diese geerbten Variablen werden jedoch als exportiert markiert 1 . Dies bedeutet, dass sie für untergeordnete Prozesse mit dem potenziell aktualisierten Wert, der von der Shell festgelegt wurde, verfügbar bleiben. Dies gilt auch für Variablen, die unter der Shell erstellt und mit demexport
Schlüsselwort exportiert wurden .Array- und andere Variablen mit komplexem Typ können nur exportiert werden, wenn ihr Name und Wert in das
name=value
Muster konvertiert werden können oder wenn ein Shell-spezifischer Mechanismus vorhanden ist (z. B .:bash
Exportiert Funktionen in die Umgebung und einige exotische, nicht POSIX-Shell-ähnlicherc
undes
exportierbare Arrays) ).Der Hauptunterschied zwischen Umgebungsvariablen und Shell-Variablen besteht also in ihrem Gültigkeitsbereich: Umgebungsvariablen sind global, während nicht exportierte Shell-Variablen für das Skript lokal sind.
Beachten Sie auch, dass moderne Shells (zumindest
ksh
undbash
) einen dritten Shell-Variablenbereich unterstützen. Variablen, die in Funktionen mit demtypeset
Schlüsselwort erstellt wurden, sind für diese Funktion lokal (Die Art und Weise, wie die Funktion deklariert wird, aktiviert / deaktiviert diese Funktionksh
, und das Persistenzverhalten unterscheidet sich zwischenbash
undksh
). Siehe /unix//a/28349/25941 Dies gilt für moderne Shells wie
ksh
,dash
,bash
und ähnliche. Die alten Bourne-Shell- und Nicht-Bourne-Syntax-Shellscsh
haben unterschiedliche Verhaltensweisen.quelle
execve()
Systemaufruf übergeben werden, damit (normalerweise) Daten während der Ausführung anderer Befehle (im selben Prozess) erhalten bleiben .IFS
in einigen Shells).rc
,es
können Arrays exportieren , um eine Ad - hoc - Codierung.bash
undrc
kann Funktionen auch mithilfe von Umgebungsvariablen exportieren (wiederum mithilfe einer speziellen Codierung).ksh93
,typeset
schränkt nur den Umfang in Funktionen mit der erklärtenfunction foo { ...; }
Syntax, nicht mit der Bourne (foo() cmd
) Syntax (und es ist statisch Scoping nicht dynamisch wie in anderen Shells).Shell-Variablen
Shell-Variablen sind Variablen, deren Gültigkeitsbereich sich in der aktuellen Shell-Sitzung befindet, beispielsweise in einer interaktiven Shell-Sitzung oder einem Skript.
Sie können eine Shell-Variable erstellen, indem Sie einem nicht verwendeten Namen einen Wert zuweisen:
Die Verwendung von Shell-Variablen dient dazu, die Daten in der aktuellen Sitzung zu verfolgen. Shell-Variablen haben normalerweise Namen mit Kleinbuchstaben.
Umgebungsvariablen
Eine Umgebungsvariable ist eine Shell-Variable, die exportiert wurde. Dies bedeutet, dass es als Variable nicht nur in der Shell-Sitzung angezeigt wird, die es erstellt hat, sondern auch für alle Prozesse (nicht nur Shells), die von dieser Sitzung aus gestartet werden.
oder
Sobald eine Shell-Variable exportiert wurde, bleibt sie exportiert, bis sie nicht mehr gesetzt ist oder bis ihre "export-Eigenschaft" entfernt wird (mit
export -n
inbash
), sodass sie normalerweise nicht erneut exportiert werden muss. Wenn Sie eine Variable mit deaktivieren, wird sie gelöschtunset
(unabhängig davon, ob es sich um eine Umgebungsvariable handelt oder nicht).Arrays und assoziative Hashes in
bash
und andere Shells können möglicherweise nicht als Umgebungsvariablen exportiert werden. Umgebungsvariablen müssen einfache Variablen sein, deren Werte Zeichenfolgen sind und deren Namen häufig aus Großbuchstaben bestehen.Die Verwendung von Umgebungsvariablen dient dazu, die Daten in der aktuellen Shell-Sitzung zu verfolgen, aber auch jedem gestarteten Prozess zu ermöglichen, an diesen Daten teilzunehmen. Der typische Fall hierfür ist die
PATH
Umgebungsvariable, die in der Shell festgelegt und später von jedem Programm verwendet werden kann, das Programme starten möchte, ohne einen vollständigen Pfad zu ihnen anzugeben.Die Sammlung von Umgebungsvariablen in einem Prozess wird häufig als "die Umgebung des Prozesses" bezeichnet. Jeder Prozess hat eine eigene Umgebung.
Umgebungsvariablen können nur "weitergeleitet" werden, dh ein untergeordneter Prozess kann die Umgebungsvariablen in seinem übergeordneten Prozess niemals ändern, und abgesehen vom Einrichten der Umgebung für einen untergeordneten Prozess beim Starten ändert ein übergeordneter Prozess möglicherweise nicht die vorhandene Umgebung von a untergeordneter Prozess.
Umgebungsvariablen können mit
env
(ohne Argumente) aufgelistet werden . Ansonsten sehen sie in einer Shell-Sitzung genauso aus wie nicht exportierte Shell-Variablen. Dies ist etwas speziell für die Shell, da die meisten anderen Programmiersprachen normalerweise keine "normalen" Variablen mit Umgebungsvariablen vermischen (siehe unten).env
kann auch verwendet werden, um die Werte einer oder mehrerer Umgebungsvariablen in der Umgebung eines Prozesses festzulegen, ohne sie in der aktuellen Sitzung festzulegen:Dies beginnt
make
damit, dass die UmgebungsvariableCC
auf den Wert gesetztclang
und aufCXX
gesetzt wirdclang++
.Es kann auch verwendet werden, um die Umgebung für einen Prozess zu löschen :
Dies beginnt
bash
aber nicht die aktuelle Umgebung auf den neuen übertragenbash
Prozess (es wird nach wie vor hat Umgebungsvariablen , wie sie neue aus seiner Schale Initialisierungsskripts erstellt).Beispiel für den Unterschied
Andere Sprachen
In den meisten Programmiersprachen gibt es Bibliotheksfunktionen, mit denen Umgebungsvariablen abgerufen und festgelegt werden können. Da Umgebungsvariablen als einfache Schlüssel-Wert-Beziehung gespeichert werden, handelt es sich normalerweise nicht um "Variablen" der Sprache. Ein Programm kann den Wert (der immer eine Zeichenfolge ist) abrufen, der einem Schlüssel (dem Namen der Umgebungsvariablen) entspricht, muss ihn dann jedoch in eine Ganzzahl oder in den Datentyp konvertieren, den die Sprache für den Wert erwartet.
In C, kann Umgebungsvariablen zugegriffen mit
getenv()
,setenv()
,putenv()
undunsetenv()
. Mit diesen Routinen erstellte Variablen werden von jedem Prozess, den das C-Programm startet, auf dieselbe Weise vererbt.Andere Sprachen können spezielle Datenstrukturen haben, um dasselbe zu erreichen, wie der
%ENV
Hash in Perl oder dasENVIRON
assoziative Array in den meisten Implementierungen vonawk
.quelle
getenv()
,setenv()
,putenv()
undunsetenv()
. Mit diesen Routinen erstellte Variablen werden von jedem Prozess, den das C-Programm startet, auf dieselbe Weise vererbt. Andere Sprachen haben möglicherweise spezielle Datenstrukturen für dasselbe wie%ENV
in Perl.exec*()
Funktionsfamilie kann auch die Umgebung für den ausgeführten Prozess festlegen.Shell-Variablen sind schwer zu duplizieren.
Umgebungsvariablen können jedoch dupliziert werden. Sie sind nur eine Liste, und eine Liste kann doppelte Einträge enthalten. Hier ist
envdup.c
genau das zu tun.Was wir kompilieren und ausführen können,
envdup
um dann auszuführenenv
, um uns zu zeigen, welche Umgebungsvariablen gesetzt sind ...Dies ist möglicherweise nur nützlich, um Fehler oder andere Unregelmäßigkeiten bei der Handhabung von Programmen zu finden
**environ
.Es sieht so aus, als würde Python 3.6 hier die Duplikate blind weitergeben (eine undichte Abstraktion), Perl 5.24 hingegen nicht. Wie wäre es mit den Muscheln?
Meine Güte, was passiert, wenn
sudo
nur der erste Umgebungseintrag bereinigt wird und dannbash
der zweite ausgeführt wird? HalloPATH
oderLD_RUN_PATH
ausnutzen. Ist Ihrsudo
(und alles andere ?) Für dieses Loch geflickt ? Sicherheits-Exploits sind weder ein "anekdotischer Unterschied" noch ein "Fehler" im aufrufenden Programm.quelle
Eine Umgebungsvariable ähnelt einer Shell-Variablen , ist jedoch nicht spezifisch für die Shell . Alle Prozesse auf Unix-Systemen verfügen über einen Speicher für Umgebungsvariablen . Der Hauptunterschied zwischen Umgebungsvariablen und Shell-Variablen besteht darin, dass das Betriebssystem alle Umgebungsvariablen Ihrer Shell an die von der Shell ausgeführten Programme übergibt , während in den von Ihnen ausgeführten Befehlen nicht auf Shell-Variablen zugegriffen werden kann.
env –
Mit dem Befehl können Sie ein anderes Programm in einer benutzerdefinierten Umgebung ausführen, ohne das aktuelle zu ändern. Bei Verwendung ohne Argument wird eine Liste der aktuellen Umgebungsvariablen gedruckt.printenv –
Der Befehl druckt alle oder die angegebenen Umgebungsvariablen.set –
Der Befehl setzt oder deaktiviert Shell-Variablen. Bei Verwendung ohne Argument wird eine Liste aller Variablen gedruckt, einschließlich Umgebungs- und Shell-Variablen sowie Shell-Funktionen.unset –
Der Befehl löscht Shell- und Umgebungsvariablen.export –
Der Befehl legt Umgebungsvariablen festquelle