Eine Umgebung ist nicht so magisch, wie es scheint. Die Shell speichert es im Speicher und übergibt es an den execve()
Systemaufruf. Der untergeordnete Prozess erbt ihn als aufgerufenen Array-Zeiger environ
. Aus der execve
Manpage:
ZUSAMMENFASSUNG
#include <unistd.h>
int execve(const char *filename, char *const argv[],
char *const envp[]);
argv
ist ein Array von Argumenten, die an das neue Programm übergeben werden.
Gemäß der Konvention sollte die erste dieser Zeichenfolgen den Dateinamen enthalten, der der ausgeführten Datei zugeordnet ist. envp
ist ein Array von Strings, üblicherweise mit der Form key = value, die als Umgebung an das neue Programm übergeben werden.
Die environ(7)
Manpage bietet auch einige Einblicke:
ZUSAMMENFASSUNG
extern char **environ;
BESCHREIBUNG
Die Variable environ
zeigt auf ein Array von Zeigern auf Zeichenfolgen, die als "Umgebung" bezeichnet werden. Der letzte Zeiger in diesem Array hat den Wert NULL
. (Diese Variable muss im Benutzerprogramm deklariert werden, wird jedoch in der Header-Datei deklariert, <unistd.h>
falls die Header-Dateien aus libc4 oder libc5 stammen und falls sie aus glibc stammen und _GNU_SOURCE definiert wurde.) Dieses Array von Strings wird für bereitgestellt der Prozess durch den exec (3) -Aufruf, der den Prozess gestartet hat.
Beide GNU-Hilfeseiten stimmen mit der POSIX-Spezifikation überein
exec(3)
Familienmitglieder (dh diejenigen, die nicht mit exec * v übereinstimmen) die Umgebungsbedingungen nicht erfüllen.exec*e
Varianten, die explizit ein env übergeben, anstatt implizit dieenviron
globale Variable zu verwenden. Dasv
bedeutet "vector" und bezieht sich auf die als Array übergebenen Befehlszeilenargumente (anstelle einer "list" (Funktion mit variabler Länge)) undexecve
ist ein Systemaufruf. Alle anderenexec*
Funktionen sind libc-Wrapper dafür.Sie haben es ein wenig falsch verstanden:
SOME_NAME=value
Erstellt eine Shell-Variable (in den meisten Shells).export SOME_NAME=value
Erstellt eine Umgebungsvariable. Die meisten Unix / Linux / * BSD-Shells verwenden beim Zugriff auf Umgebungsvariablen und Shell-Variablen die gleiche Syntax.Im weiteren Sinne ist eine "Umgebung" nur die Information, die mit der Programmausführung einhergeht. In C - Programmen können Sie den Prozess - ID mit einem finden
getpid()
Anruf, in einem Shell - Programm würden verwenden Sie einen variablen Zugang:$$
. Die Prozess-ID ist nur ein Teil der Programmumgebung. Ich glaube, der Begriff "Umgebung" kommt von einigen der theoretischeren Informatik-Themen, wie der Modellierung der Programmausführung. Modelle der Programmausführung haben eine Umgebung, "die die Assoziationen zwischen Variablen und ihren Werten enthält".Und diese letztere, stärkere Definition ist, was eine "Umgebung" für Unix / Linux / * BSD-Shells ist: eine Assoziation zwischen Namen ("Variablen") und ihren Werten. Bei den meisten Unix-Shells handelt es sich bei den Werten um Zeichenfolgen, obwohl dies nicht mehr so genau wie früher der Fall ist. Ksh, Zsh und Bash haben heutzutage alle Variablen eingegeben. Sogar Shell-Funktionsdefinitionen können exportiert werden.
Die Verwendung einer von einfachen Shell-Variablen getrennten Umgebung umfasst die
fork/exec
Methode zum Starten eines neuen Prozesses, den alle Unix-Benutzer verwenden. Wenn Sieexport
ein Name / Wert-Paar haben, ist dieses Name / Wert-Paar in der Umgebung neuer ausführbarer Dateien vorhanden, die von der Shell mit einemexecve(2)
Systemaufruf gestartet werden (normalerweise nach afork(2)
, außer wenn derexec
Shell-Befehl verwendet wurde).Im Anschluss an
execve()
hat diemain()
Funktion new binary ihre Befehlszeilenargumente, die Umgebung (gespeichert als NULL-terminiertes Array von Zeigern aufvar=value
Zeichenfolgen, sieheenviron(7)
Manpage). Ein anderer geerbter Status umfasstulimit
Einstellungen, das aktuelle Arbeitsverzeichnis und alle geöffneten Dateideskriptoren, für die derexecve()
Aufrufer FD_CLOEXEC nicht festgelegt hat. Der aktuelle Status des Tty (Echo aktiviert, Raw-Modus usw.) kann auch als Teil des Ausführungsstatus betrachtet werden, der von einem neu erstelltenexec
Prozess geerbt wurde .In der
bash
Beschreibung der Ausführungsumgebung im Handbuch finden Sie Informationen zu einfachen Befehlen (außer integrierten oder Shell-Funktionen).Die Unix-Umgebung unterscheidet sich zumindest von einigen anderen Betriebssystemen: VMS-"Lexika" konnten von einem untergeordneten Prozess geändert werden, und diese Änderung war im übergeordneten Prozess sichtbar. Ein VMS
cd
in einem untergeordneten Prozess wirkt sich auf das Arbeitsverzeichnis des übergeordneten Prozesses aus. Zumindest unter bestimmten Umständen, und mein Gedächtnis kann mich verfehlen.Einige Umgebungsvariablen sind gut bekannt
$HOME
,$PATH
,$LD_LIBRARY_PATH
und andere. Einige sind für ein bestimmtes Programmiersystem üblich, sodass eine übergeordnete Shell sehr viele spezielle Informationen an ein Programm weitergeben kann, z. B. ein bestimmtes temporäres Verzeichnis oder eine Benutzer-ID und ein Kennwort, die nicht in angezeigt werdenps -ef
. Einfache CGI-Programme erben beispielsweise über Umgebungsvariablen viele Informationen vom Webserver.quelle
SOME_NAME=value command
wird die Umgebungsvariable SOME_NAME für diesen Befehlsaufruf festgelegt. Verwirrenderweise scheint die gleichnamige Shell-Variable nicht gesetzt zu werden.SOME_NAME=value command
sich wider Erwarten verhalten, ist eine spezielle Syntax, die bedeutet, dass Sie der an den Befehl übergebenen Umgebung SOME_NAME hinzufügen, die Variablen dieser Shell jedoch nicht anderweitig ändern.fork()
ed, aber sie tun erhalten (Kopien) Shell - Variablen.Umgebungsvariablen in ihrer ursprünglichsten Form sind nur eine Reihe von Name / Wert-Paaren. Wie in der bash-Manpage (
man 1 bash
) im Abschnitt UMWELT beschrieben:In der Praxis können Sie damit ein Verhalten definieren, das für Programme, die über die aktuelle Shell aufgerufen werden, freigegeben oder eindeutig ist. Wenn Sie beispielsweise
crontab
oder verwendenvisudo
, können Sie dieEDITOR
Umgebungsvariable definieren, um einen anderen Editor als den zu definieren, den Ihr System standardmäßig verwenden würde. Das Gleiche gilt für Dinge wie denman
Befehl, mit dem in IhrerPAGER
Umgebung ermittelt wird, mit welchem Pager-Programm die Ausgabe der Manpage angezeigt werden soll.Sehr viele Unix-Befehle lesen die Umgebung und abhängig davon, was dort eingestellt ist, ändern sie ihre Ausgabe / Verarbeitung / Aktion. Einige werden geteilt, andere sind programmspezifisch. Die meisten Manpages enthalten Informationen darüber, wie sich die Umgebungsvariable auf das beschriebene Programm auswirkt.
Andere praktische Abbildungen beziehen sich beispielsweise auf Systeme mit mehreren Oracle-Installationen auf derselben Plattform. Durch die Einstellung
ORACLE_HOME
wird die gesamte Suite der Oracle-Befehle (wie von IhrerPATH
Umgebungsvariablen geladen ) aus diesem Verzeichnis der obersten Ebene abgerufen. Das gleiche gilt für andere Programme wie Java mit seinerJAVA_HOME
Umgebungsvariablen.Bash selbst hat viele Umgebungsvariablen, die das Verhalten einer Reihe von Dingen wie Verlauf (
HISTSIZE
,HISTFILE
usw.), Bildschirmgröße (COLUMNS
), Gebietsschema (FIGNORE
,GLOBIGNORE
) und Zeichencodierung / -decodierung (LANG
,LC_*
), Eingabeaufforderung (PS1
..PS4
) und ändern können usw. (suche erneut das Wissen von der Bash-Manpage).Sie können auch Skripte / Programme schreiben, die Ihre eigenen benutzerdefinierten Umgebungsvariablen verwenden (um Einstellungen zu übergeben oder Funktionen zu ändern).
quelle
"Umgebungsvariablen" sind dynamisch benannte Werte, die sich auf das Verhalten von Prozessen auf einem Computer auswirken können.
Sie sind Teil der Betriebsumgebung, in der ein Prozess ausgeführt wird. Beispielsweise kann ein ausgeführter Prozess den Wert der TEMP-Umgebungsvariablen abfragen, um einen geeigneten Speicherort für temporäre Dateien zu ermitteln, oder die Variable HOME oder USERPROFILE, um die Verzeichnisstruktur des Benutzers zu ermitteln, der den Prozess ausführt.
Weitere Informationen hier → http://en.wikipedia.org/wiki/Environment_variable .
Alles, was Sie über Umgebungsvariablen wissen möchten ... ↑
quelle
Für diese Antwort sind einige Kenntnisse und Erfahrungen im Umgang mit Shell-Skripten mit den Begriffen Variable, Wert, Variablensubstitution, Eingabeaufforderung, Echo, Kernel, Shell, Dienstprogramm, Sitzung und Prozess erforderlich.
Eine Umgebungsvariable (envar) ist ein Satz global definierter Variablen, die das Verhalten eines bestimmten Prozesses auf dem Betriebssystem eines Computers beeinflussen können.
1. Eine beispielhafte Einführung:
Wir ersetzen Envars durch a
$
und Großbuchstaben . Zum Beispiel:$PS1
.Wir können eine Envar folgendermaßen drucken:
$PS1
Enthält den Wert der Unix-Eingabeaufforderung. Sagen wir, seine nativen Werte sind\u
\w
$
.\u
steht für (aktuellen) Benutzer,\w
steht für Arbeitsverzeichnis,$
ist die Eingabeaufforderung zu begrenzen.Also, wenn wir tun:
echo $PS1
Wir sehen die Werte\u
,\w
und das Dollarzeichen am Ende.Wir könnten das Unix-Verhalten in diesem Kontext ändern, wenn wir die Werte dieser envar ändern. Zum Beispiel:
Nun sieht die Eingabeaufforderung so aus (vorausgesetzt, das Arbeitsverzeichnis heißt "John"):
Auf die gleiche Weise, die wir tun könnten
PS1="Hello, I'm your prompt >"
, werden wirecho $PS1
bringen:In Bash 4.xx können wir mit dem
env
Befehl ALLE Envars im System drucken . Ich schlage vor,env
im Terminal auszuführen und mir die Ausgabe anzuschauen.2. Wie werden diese Daten angezeigt und bearbeitet:
Im Terminal einer Sitzung können wir die mit Bash gelieferten Envars anpassen.
Die oben genannten Änderungen sind in der Regel vorübergehend und aus folgenden Gründen:
Jede Sitzung (die keine Untersitzung ist) ist eindeutig, und mehrere Prozesse können gleichzeitig ausgeführt werden (jeder mit einem eigenen Satz von Envars). In der Regel erfolgt jedoch eine Vererbung von Sitzung 0 zu Sitzung 1 und höher.
Änderungen, die wir an einem Prozess vornehmen, sind einzigartig und werden abgebrochen, wenn wir ihn schließen, ohne ihn auf irgendeine Weise zu speichern.
Wie können wir diese Änderungen speichern:
Abhängig vom ausgewählten Bereich gibt es verschiedene Möglichkeiten zum Speichern von envar-Änderungen. Hier sind verschiedene Bereiche (Ebenen) für solche Änderungen:
Wo werden envar-Daten gespeichert:
Unix besteht aus drei Hauptschichten: Kernel, Shell und Dienstprogramme. AFAIK Jede Shell hat ihre eigenen Envars, die hauptsächlich oder ausschließlich in der Shell erstellt werden.
Der spezifische Ort, an dem diese global geändert werden müssen, ist normalerweise,
/etc/profile
obwohl wir dies.bashrc
natürlich auch tun können .3. Neue Envars erstellen:
Wir können neue Envars erschaffen und hier ist ein Weg; Ab Bash 4.xx gibt es keinen nativen Enavar-Namen
MESSAGE
(wie gesagt, Envars werden normalerweise in Großbuchstaben geschrieben).wird es für uns erstellen, und jetzt, wenn wir Echo eingeben
$MESSAGE
, bekommen wirhello world!
.Wenn wir
bash
in unserer aktuellen Arbeitssitzung (Fenster) ausführen , würden wir eine neue Bash-Untersitzung starten und werden nicht mehr im ursprünglichen Prozess arbeiten, es sei denn, wir führen ausexit
.Hinweis: In Betriebssystemen mit einem Terminalemulator (wie dem Ubuntu-Desktop) wird eine Untersitzung normalerweise im selben Fenster ausgeführt, eine neue Sitzung in einem anderen Fenster ist jedoch keine Untersitzung der vorhandenen Sitzung (dies ist ein benachbarter Prozess). .
Hinweis: Verwenden Sie keine Sonderzeichen in envar-Werten wie! oder sie werden nicht gespeichert.
Exportieren der Envar aus der ursprünglichen Sitzung in alle Untersitzungen:
Wir können die in der ersten Sitzung erstellte envar weiterhin verwenden, auch in der zweiten Sitzung, ohne sie in den conf-Dateien auf Benutzer- oder globaler Ebene zu registrieren (siehe folgende Daten). So geht's:
Gehen Sie zur ursprünglichen Sitzung (ob im aktuellen oder in einem anderen Fenster) und führen Sie Folgendes aus:
Verwenden Sie beim Exportieren kein
$
Zeichen.Es wird jetzt in alle Untersitzungen exportiert. Wenn Sie
echo $MESSAGE
eine Untersitzung durchführen, egal ob von Ihrem oder einem anderen Benutzer, wird diese gedruckt.Beachten Sie, dass interne Shell-Variablen, wie z. B.,
PS1
nicht exportiert werden sollten. Wenn Sie sie jedoch aus einem beliebigen Grund exportieren möchten und sie nicht angezeigt werden, führen Sie sie nichtbash
nachexport
, sondern nach dem Export ausbash –norc
.4. Die $ PATH-Envar:
$PATH
ist das envar, das Benutzer normalerweise am meisten ändern.Wenn wir
echo $PATH
, werden wir diesen Stream sehen:Die gedruckten Werte dieser Variable werden dort durch Doppelpunkte (:) getrennt, aber hier ist eine möglicherweise bequemere Möglichkeit (dies sind die gleichen Werte):
Dies sind Verzeichnisse, nach denen gesucht werden muss, wenn ein Dienstprogramm ausgeführt wird.
Wenn Sie ausführen
which echo
, erhalten Sie den Speicherort der Datei. Beispielsweise wird möglicherweise festgestellt, dass sie in vorhanden ist/bin/echo
.Basierend darauf müssen wir nicht echo envar eingeben, um die Werte des evnar anzuzeigen. Wir können auch:
Die envar wird weiterhin ausgeführt, zum Beispiel:
Gibt uns
Genauso wie:
Gibt uns
Hinweis:
$HOME
wird als abgekürzt~
.Die System- $ PATH-Beziehungen und eine mögliche Benutzerinteraktion:
Wenn Sie in Bash 4.xx ein Dienstprogramm ohne vollständigen Pfad verwenden, verwendet das System alle sechs oben genannten Werte der
$PATH
envar. Es beginnt also/user/local/bin
mit dem gesamten Inhalt, der nach derecho
ausführbaren Datei sucht .In diesem Fall hört es bei auf
/bin/echo
, in welchem Fall sich die ausführbare Datei befindet.Daher besteht der Hauptgrund, warum wir die
$PATH
envar anpassen könnten, darin, ausführbare Dateien zu installieren, die keinem ihrer nativen Werte entsprechen.Nachdem wir solche ausführbaren Dateien installiert haben, sollten wir ihren
$PATH
Wert entsprechend festlegen und dann in der Lage sein, mit ihnen zu arbeiten.5. Anhang - erweitern
$PATH
:Wir können
export $PATH
Untersitzungen (einschließlich Bash-Erweiterungen wie WP-CLI für WordPress oder Drush für Drupal) auf folgende Weise bashen:Dies wird einen neuen Wert hinzufügen
/home/John
zu$PATH
, und dann direkt danach, wird es keine nativen Werte (rechts hinter dem Doppelpunkt) annektiert, die unter der Syntax gespeichert werden$PATH
.Eine solche dauerhafte Änderung kann im entsprechenden Skript normalerweise unter
/etc/profile
und unter dem Namen vorgenommen werden.bashrc
.quelle
!
einem nicht funktionierenden Wert einer Umgebungsvariablen, der sich direkt unter einem Beispiel befindet, das dessen Funktion zeigt, eine falsche Vorstellung von Untersitzungen, ziemlich bizarre Ratschläge, was zu tun ist nach dem Exportieren einer Shell-Variablen und einer falschen Vorstellung von globalen Umgebungsvariablen.warning about ! in an environment variable value not working that is right below an example showing it working
? Bitte zum Beispiel.quite bizarre advice about what to do after exporting a shell variable
, was genau meinst du?false notion of global environment variables
, was genau meinst du?