Lesen und Einrichten von Umgebungs- und Shell-Variablen unter Linux

Einführung

Wenn Sie mit Ihrem Server über eine Shell-Sitzung interagieren, gibt es viele Informationen, die Ihre Shell kompiliert, um ihr Verhalten und den Zugriff auf Ressourcen zu bestimmen. Einige dieser Einstellungen sind innerhalb der Konfigurationseinstellungen enthalten und andere werden durch Benutzereingabe bestimmt.

Eine Möglichkeit, wie die Shell alle diese Einstellungen und Details verfolgt, ist ein Bereich, den sie als Umgebung bezeichnet. Die Umgebung ist ein Bereich, den die Shell jedes Mal, wenn sie eine Sitzung startet, erstellt und der Variablen enthält, die Systemeigenschaften definieren.

In diesem Leitfaden besprechen wir, wie Sie mit der Umgebung interagieren und Umgebungs- und Shell-Variablen interaktiv und über Konfigurationsdateien lesen oder einrichten.

Funktionsweise der Umgebung und Umgebungsvariablen

Bei jedem Starten einer Shell-Sitzung findet ein Prozess statt, der Informationen sammelt und kompiliert, die dem Shell-Prozess und seinen Unterprozessen verfügbar sein sollen. Die Daten für diese Einstellungen bezieht er aus einer Vielzahl verschiedener Dateien und Einstellungen auf dem System.

Die Umgebung stellt ein Medium bereit, über das der Shell-Prozess Einstellungen erhalten oder einrichten kann und diese wiederum an seine Unterprozesse weitergibt.

Die Umgebung ist als Zeichenketten implementiert, die Schlüsselwertpaare darstellen. Werden mehrere Werte übergeben, werden sie typischerweise durch Doppelpunkte (:) getrennt. Jedes Paar sieht allgemein etwa so aus:

KEY=value1:value2:... 

Wenn der Wert signifikante Leerzeichen enthält, werden Anführungszeichen verwendet:

KEY="value with spaces" 

Die Schlüssel in diesen Szenarien sind Variablen. Sie können einer von zwei Typen sein, Umgebungsvariablen oder Shell-Variablen.

Umgebungsvariablen sind Variablen, die für die aktuelle Shell definiert sind und an alle untergeordneten Shells oder Prozesse vererbt werden. Umgebungsvariablen werden verwendet, um Informationen an Prozesse zu übergeben, die von der Shell gestartet werden.

Shell-Variablen sind Variablen, die ausschließlich innerhalb der Shell enthalten sind, in der sie festgelegt oder definiert wurden. Sie werden oft verwendet, um kurzlebige Daten wie das aktuelle Arbeitsverzeichnis zu verfolgen.

Gemäß der Konvention werden diese Arten von Variablen normalerweise mit Großbuchstaben definiert. Dies hilft dem Benutzer, Umgebungsvariablen innerhalb anderer Kontexte zu unterscheiden.

Ausgeben von Shell- und Umgebungsvariablen

Jede Shell-Sitzung verfolgt ihre eigenen Shell- und Umgebungsvariablen. Wir können auf diese auf verschiedene Weise zugreifen.

Wir können eine Liste aller unsere Umgebungsvariablen sehen, indem wir die Befehle env oder printenv verwenden. In ihrem Standardzustand sollten sie genau gleich funktionieren:

  • printenv
OutputSHELL=/bin/bash TERM=xterm USER=demouser LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca:... MAIL=/var/mail/demouser PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games PWD=/home/demouser LANG=en_US.UTF-8 SHLVL=1 HOME=/home/demouser LOGNAME=demouser LESSOPEN=| /usr/bin/lesspipe %s LESSCLOSE=/usr/bin/lesspipe %s %s _=/usr/bin/printenv 

Dies ist ziemlich typisch für die Ausgabe sowohl von printenv als auch env. Der Unterschied zwischen den beiden Befehlen ist nur in ihrer spezifischeren Funktionalität sichtbar. Beispielsweise können Sie mit printenv die Werte einzelner Variablen anfordern:

  • printenv SHELL
Output/bin/bash 

Mit env hingegen können Sie die Umgebung, in der Programme ausgeführt werden, ändern, indem Sie einen Satz von Variablendefinitionen wie folgt an einen Befehl übergeben:

  • env VAR1="value" command_to_run command_options

Da, wie wir vorstehend gelernt haben, untergeordnete Prozesse typischerweise die Umgebungsvariablen des übergeordneten Prozesses erben, bietet Ihnen dies die Möglichkeit, Werte zu überschreiben oder zusätzliche Variablen für den untergeordneten Prozess hinzuzufügen.

Wie Sie in der Ausgabe unseres Befehls printenv sehen können, gibt es eine ganze Reihe von Umgebungsvariablen, die, ohne unsere Eingabe, durch unsere Systemdateien und Prozesse eingerichtet wurden.

Diese zeigen die Umgebungsvariablen, aber wie sehen wir Shell-Variablen?

Hierfür kann der Befehl set verwendet werden. Wenn wir set ohne zusätzliche Parameter eingeben, erhalten wir eine Liste aller Shell-Variablen, Umgebungsvariablen, lokalen Variablen und Shell-Funktionen:

  • set
OutputBASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() . . . 

Dies ist normalerweise eine riesige Liste. Wahrscheinlich möchten Sie sie in ein Pager-Programm leiten, um die Menge der Ausgabe leichter bewältigen zu können:

  • set | less

Die Menge zusätzlicher Informationen, die wir zurückerhalten, ist etwas überwältigend. Wahrscheinlich müssen wir nicht alle Bash-Funktionen kennen, die beispielsweise definiert sind.

Wir können die Ausgabe bereinigen, indem wir angeben, dass set im POSIX-Modus arbeiten soll, wodurch die Shell-Funktionen nicht ausgegeben werden. Wir können dies in einer Unter-Schell ausführen, sodass es unsere aktuelle Umgebung nicht verändert:

  • (set -o posix; set)

Dies listet alle Umgebungs- und Shell-Variablen auf, die definiert sind.

Wir können versuchen, diese Ausgabe mit der Ausgabe der Befehle env oder printenv zu vergleichen, um zu versuchen, nur eine Liste der Shell-Variablen zu erhalten, aber dies wird aufgrund der unterschiedlichen Art und Weise, wie diese Befehle Informationen ausgeben, nicht perfekt sein:

  • comm -23 <(set -o posix; set | sort) <(env | sort)

Es werden wahrscheinlich immer noch einige Umgebungsvariablen enthalten sein, da der Befehl set Werte in Anführungszeichen ausgibt, währen die Befehle printenv und env die Werte von Zeichenketten nicht in Anführungszeichen setzen.

Dennoch sollte dies Ihnen einen guten Überblick über die Umgebungs- und Shell-Variablen geben, die in Ihrer Sitzung festgelegt sind.

Diese Variablen werden für alle möglichen Dinge verwendet. Sie bieten einen alternativen Weg, um zwischen Prozessen dauerhafte Werte für die Sitzung zu setzen, ohne Änderungen in eine Datei zu schreiben.

Häufige Umgebungs- und Shell-Variablen

Einige Umgebungs- und Shell-Variablen sind sehr nützlich und werden ziemlich oft referenziert. Hier sind einige häufige Umgebungsvariablen, denen Sie begegnen werden:

  • SHELL: Dies beschreibt die Shell, die alle von Ihnen eingegebenen Befehle interpretiert. In den meisten Fällen wird dies standardmäßig Bash sein, jedoch können auch andere Werte festgelegt werden, wenn Sie andere Optionen bevorzugen.
  • TERM: Dies gibt die Art des Terminals an, das bei der Ausführung der Shell emuliert werden soll. Es können verschiedene Hardware-Terminals für unterschiedliche Betriebsanforderungen emuliert werden. Normalerweise müssen Sie sich darüber aber keine Gedanken machen.
  • USER: Der aktuelle angemeldete Benutzer.
  • PWD: Das aktuelle Arbeitsverzeichnis.
  • OLDPWD: Das vorherige Arbeitsverzeichnis. Dieses wird von der Shell beibehalten, um durch Ausführen von cd - wieder in Ihr vorheriges Verzeichnis zu wechseln.
  • LS_COLORS: Dies definiert Farbcodes, die verwendet werden, um dem Befehl Is optional eine farbige Ausgabe hinzuzufügen. Dies wird verwendet, um verschiedene Dateitypen zu unterscheiden und dem Benutzer auf einen Blick mehr Informationen zu bieten.
  • MAIL: Der Pfad zur Mailbox des aktuellen Benutzers.
  • PATH: Eine Liste von Verzeichnissen, die das System bei der Suche nach Befehlen überprüfen wird. Wenn ein Benutzer einen Befehl eingibt, überprüft das System die Verzeichnisse in dieser Reihenfolge auf die ausführbare Datei.
  • LANG: Die aktuelle Sprach- und Lokalisierungseinstellungen, einschließlich der Zeichencodierung.
  • HOME: Das Heimatverzeichnis des aktuellen Benutzers.
  • _: Der letzte zuvor ausgeführte Befehl.

Zusätzlich zu diesen Umgebungsvariablen gibt es noch einige Shell-Variablen, die Sie oft sehen werden:

  • BASHOPTS: Die Liste der Optionen, die bei der Ausführung von Bash verwendet wurden. Dies kann nützlich sein, um herauszufinden, ob die Shell-Umgebung so funktioniert, wie Sie es wünschen.
  • BASH_VERSION: Die Version von Bash, die ausgeführt wird, in menschenlesbarer Form.
  • BASH_VERSINFO: Die Version von Bash, in maschinenlesbarer Ausgabe.
  • COLUMNS: Die Anzahl der Spaltenbreite, die zur Ausgabe auf dem Bildschirm verwendet wird.
  • DIRSTACK: Der Stack von Verzeichnissen, die mit den Befehlen pushd und popd verfügbar sind.
  • HISTFILESIZE: Anzahl der Zeilen der Befehlshistorie, die in einer Datei gespeichert werden.
  • HISTSIZE: Anzahl der Zeilen der Befehlshistorie, die im Speicher erlaubt sind.
  • HOSTNAME: Der Hostname des Computers zu diesem Zeitpunkt.
  • IFS: Das interne Feldtrennzeichen zur Trennung der Eingabe in der Befehlszeile. Standardmäßig ist dies ein Leerzeichen.
  • PS1: Die primäre Definition der Eingabeaufforderung. Damit wird definiert, wie Ihre Eingabeaufforderung beim Starten einer Shell-Sitzung aussieht. Der PS2 wird verwendet, um sekundäre Eingabeaufforderungen zu deklarieren, wenn sich ein Befehl über mehrere Zeilen erstreckt.
  • SHELLOPTS: Shell-Optionen, die mit der Option set festgelegt werden können.
  • UID: Die UID des aktuellen Benutzers.

Einstellen von Shell- und Umgebungsvariablen

Um den Unterschied zwischen Shell- und Umgebungsvariablen besser zu verstehen und die Syntax für die Einstellung dieser Variablen einzuführen, werden wir eine kleine Demonstration durchführen.

Erstellen von Shell-Variablen

Wir beginnen mit der Definition einer Shell-Variable innerhalb unserer aktuellen Sitzung. Dies ist einfach zu erreichen; wir müssen nur einen Namen und einen Wert angeben. Wir halten uns an die Konvention, den Variablennamen in Großbuchstaben zu schreiben, und setzen ihn auf eine einfache Zeichenkette.

  • TEST_VAR='Hello World!'

Hier haben wir Anführungszeichen verwendet, da der Wert unserer Variable ein Leerzeichen enthält. Außerdem haben wir einfache Anführungszeichen verwendet, weil das Ausrufezeichen ein Sonderzeichen in der Bash-Shell ist, das sich normalerweise in den Bash-Verlauf ausdehnt, wenn es nicht mit einem Escape-Zeichen versehen oder in einfache Anführungszeichen gesetzt wird.

Wir haben nun eine Shell-Variable. Diese Variable ist in unserer aktuellen Sitzung verfügbar, wird aber nicht an untergeordnete Prozesse übergeben.

Wir können dies sehen, indem wir mit dem Befehl „grep“ in der Ausgabe set nach unserer neuen Variable suchen:

  • set | grep TEST_VAR
OutputTEST_VAR='Hello World!' 

Wir können überprüfen, dass es sich nicht um eine Umgebungsvariable handelt, indem wir das Gleiche mit printenv versuchen:

  • printenv | grep TEST_VAR

Es sollte keine Ausgabe zurückgegeben werden.

Nehmen wir dies zum Anlass, eine Möglichkeit zu demonstrieren, wie auf den Wert einer beliebigen Shell- oder Umgebungsvariablen zugegriffen werden kann.

  • echo $TEST_VAR
OutputHello World! 

Wie Sie sehen können, referenzieren Sie den Wert einer Variable, indem Sie ihr ein $-Zeichen voranstellen. Die Shell bezeichnet damit, dass sie den Wert der Variable ersetzen soll, wenn sie auf diese stößt.

Jetzt haben wir eine Shell-Variable. Sie sollte nicht an untergeordnete Prozesse übergeben werden. Wir können zur Demonstration eine neue Bash-Shell aus unserer aktuellen heraus starten:

  • bash
  • echo $TEST_VAR

Wenn wir bash eingeben, um eine untergeordnete Shell zu starten, und dann versuchen, auf den Inhalt der Variable zuzugreifen, wird nichts zurückgegeben. Das haben wir erwartet.

Gehen Sie zurück zu unserer ursprünglichen Shell, indem Sie exit eingeben:

  • exit

Erstellen von Umgebungsvariablen

Lassen Sie uns nun unsere Shell-Variable in eine Umgebungsvariable verwandeln. Wir können dies tun, indem wir die Variable exportieren. Der Befehl dazu heiß passenderweise:

  • export TEST_VAR

Dadurch wird unsere Variable in eine Umgebungsvariable umgewandelt. Wir können dies überprüfen, indem wir unsere Umgebungsliste erneut überprüfen:

  • printenv | grep TEST_VAR
OutputTEST_VAR=Hello World! 

Diesmal wird unsere Variable angezeigt. Versuchen wir unser Experiment mit unserer untergeordneten Shell:

  • bash
  • echo $TEST_VAR
OutputHello World! 

Klasse! Unsere untergeordnete Shell hat die Variable, die von ihrer übergeordneten Shell gesetzt wurde, erhalten. Bevor wir diese untergeordnete Shell verlassen, versuchen wir, eine andere Variable zu exportieren. Wir können Umgebungsvariablen in einem einzigen Schritt wie folgt setzen:

  • export NEW_VAR="Testing export"

Testen Sie, dass sie als Umgebungsvariable exportiert wird:

  • printenv | grep NEW_VAR
OutputNEW_VAR=Testing export 

Lassen Sie uns nun wieder in unsere ursprüngliche Shell gehen:zurückkehren:

  • exit

Sehen wir, ob unsere neue Variable verfügbar ist:

  • echo $NEW_VAR

Es wird nichts zurückgegeben.

Das liegt daran, dass Umgebungsvariablen nur an untergeordnete Prozesse übergeben werden. Es gibt keine integrierte Möglichkeit, Umgebungsvariablen der übergeordneten Shell zu setzen. Dies ist in den meisten Fällen gut und verhindert, dass Programme die Betriebsumgebung beeinträchtigen, aus der sie aufgerufen wurden.

Die Variable NEW_VAR wurde in unserer untergeordneten Shell als Umgebungsvariable gesetzt. Diese Variable würde für sie selbst und alle untergeordneten Shells und Prozesse verfügbar sein. Beim Verlassen zurück in unsere Haupt-Shell wurde diese Umgebung zerstört.

Herunterstufen und Zurücksetzen von Variablen

Wir haben noch immer unsere Variable TEST_VAR als Umgebungsvariable definiert. Wir können sie wieder in eine Shell-Variable umwandeln, indem wir Folgendes eingeben:

  • export -n TEST_VAR

Sie ist keine Umgebungsvariable mehr:

  • printenv | grep TEST_VAR

Sie ist jedoch noch immer eine Shell-Variable:

  • set | grep TEST_VAR
OutputTEST_VAR='Hello World!' 

Wenn wir eine Variable, egal ob Shell- oder Umgebungsvariable, komplett zurücksetzen möchten, können wir dies mit dem Befehl unset tun:

  • unset TEST_VAR

Wir können überprüfen, dass sie nicht mehr gesetzt ist:

  • echo $TEST_VAR

Es wird nichts zurückgegeben, da die Variable zurückgesetzt wurde.

Setzen von Umgebungsvariablen bei der Anmeldung

Wir haben bereits erwähnt, dass viele Programme Umgebungsvariablen verwenden, um die Besonderheiten der Funktionsweise zu entscheiden. Wir wollen nicht jedes Mal, wenn wir eine neue Shell-Sitzung starten, wichtige Variablen setzen müssen, und wir haben bereits gesehen, wie viele Variablen beim Anmelden bereits gesetzt sind, also wie können wir Variablen automatisch erstellen und definieren?

Dies ist tatsächlich ein komplexeres Problem, als es auf den ersten Blick scheint, aufgrund der zahlreichen Konfigurationsdateien, die die Bash-Shell liest, je nachdem, wie sie gestartet wird.

Der Unterschied zwischen Anmelde-, Nicht-Anmelde-, interaktiven und nicht-interaktiven Shell-Sitzungen

Die Bash-Shell liest verschiedene Konfigurationsdateien, je nachdem, wie die Sitzung gestartet wird.

Ein Unterschied zwischen verschiedenen Sitzungen ist, ob die Shell als Anmelde– oder Nicht-Anmelde-Sitzung gestartet wird.

Eine Anmelde-Shell ist eine Shell-Sitzung, die mit der Authentifizierung des Benutzers beginnt. Wenn Sie sich in einer Terminal-Sitzung oder über SSH anmelden und sich authentifizieren, wird Ihre Shell-Sitzung als Anmelde-Shell gesetzt.

Wenn Sie aus Ihrer authentifizierten Sitzung eine neue Shell-Sitzung starten, wie wir es mit dem Aufruf des Befehls bash über das Terminal getan haben, wird eine Nicht-Anmelde-Shell-Sitzung gestartet. Sie wurden beim Start Ihrer untergeordneten Shell nicht nach Ihren Authentifizierungsdetails gefragt.

Eine weitere Unterscheidung, die vorgenommen werden kann, ist, ob eine Shell-Sitzung interaktiv oder nicht interaktiv ist.

Eine interaktive Shell-Sitzung ist eine Shell-Sitzung, die an ein Terminal gebunden ist. Eine nicht interaktive Shell-Sitzung ist eine Shell-Sitzung, die nicht an eine Terminal-Sitzung gebunden ist.

Jede Shell-Sitzung wird also entweder als Anmelde oder Nicht-Anmelde und interaktiv oder nicht interaktiv klassifiziert.

Eine normale Sitzung, die mit SSH beginnt, ist normalerweise eine interaktive Anmelde-Shell. Ein Skript, das von der Befehlszeile ausgeführt wird, wird normalerweise in einer nicht interaktiven, Nicht-Anmelde-Shell ausgeführt. Eine Terminal-Sitzung kann eine beliebige Kombination dieser beiden Eigenschaften sein.

Ob eine Shell-Sitzung als Anmelde- oder Nicht-Anmelde-Shell klassifiziert wird, hat Auswirkungen darauf, welche Dateien zur Initialisierung der Shell-Sitzung gelesen werden.

Eine als Anmelde-Sitzung gestartete Sitzung liest zuerst die Konfigurationsdetails aus der Datei /etc/profile. Sie sucht nach der ersten Anmelde-Shell-Konfigurationsdatei im Heimatverzeichnis des Benutzers, um benutzerspezifische Konfigurationsdetails zu erhalten.

Sie liest die erste Datei, die sie aus ~/.bash_profile, ~/.bash_login und ~/.profile finden kann, und liest keine weiteren Dateien.

Im Gegensatz dazu liest eine als Nicht-Anmelde-Shell definierte Sitzung /etc/bash.bashrc und dann die benutzerspezifische Datei ~/.bashrc, um ihre Umgebung zu erstellen.

Nicht-interaktive Shells lesen die Umgebungsvariable namens BASH_ENV und lesen die angegebene Datei, um die neue Umgebung zu definieren.

Implementieren von Umgebungsvariablen

Wie Sie sehen können, gibt es eine Vielzahl von verschiedenen Dateien, die wir normalerweise für die Platzierung unserer Einstellungen ansehen müssten.

Dies bietet eine Menge Flexibilität, die in bestimmten Situationen hilfreich sein kann, in denen wir bestimmte Einstellungen in einer Anmelde-Shell und andere Einstellungen in einer Nicht-Anmelde-Shell wünschen. Die meiste Zeit werden jedoch die gleichen Einstellungen in beiden Situationen wünschen.

Glücklicherweise konfigurieren die meisten Linux-Distributionen die Anmelde-Konfigurationsdateien als Quelle für die Nicht-Anmelde-Konfigurationsdateien. Das bedeutet, dass Sie Umgebungsvariablen, die Sie in beiden Fällen benötigen, in den Nicht-Anmelde-Konfigurationsdateien definieren können. Sie werden dann in beiden Szenarien gelesen.

Normalerweise werden wir benutzerspezifische Umgebungsvariablen setzen, und wir werden normalerweise wünschen, dass unsere Einstellungen sowohl in Anmelde- als auch Nicht-Anmelde-Shells verfügbar sind. Das bedeutet, dass sich der Ort zur Definition dieser Variablen in der Datei ~/.bashrc befindet.

Öffnen Sie nun diese Datei:

  • nano ~/.bashrc

Diese wird wahrscheinlich bereits eine ganze Menge Daten enthalten. Die meisten Definitionen hier sind für das Setzen von Bash-Optionen, wobei diese nichts mit Umgebungsvariablen zu tun haben. Sie können Umgebungsvariablen genauso setzen wie Sie es über die Befehlszeile tun würden:

  • export VARNAME=value

Neue Umgebungsvariablen können an beliebiger Stelle in der Datei ~/.bashrc eingefügt werden, solange sie nicht in der Mitte eines anderen Befehls oder einer for-Schleife stehen. Anschließend können wir die Datei speichern und schließen. Wenn Sie das nächste Mal eine Shell-Sitzung starten, wird Ihre Umgebungsvariablendeklaration gelesen und an die Shell-Umgebung übergeben. Sie können Ihre aktuelle Sitzung zwingen, die Datei nun zu lesen, indem Sie Folgendes eingeben:

  • source ~/.bashrc

Wenn Sie systemweite Variablen setzen müssen, sollten Sie darüber nachdenken, diese in /etc/profile, /etc/bash.bashrc oder /etc/environment hinzuzufügen.

Zusammenfassung

Umgebungs- und Shell-Variablen sind in Ihren Shell-Sitzungen immer vorhanden und können sehr nützlich sein. Sie sind eine interessante Möglichkeit für einen übergeordneten Prozess, die Konfigurationsdetails für seinen untergeordneten Prozess festzulegen und bieten eine Möglichkeit, Optionen außerhalb von Dateien zu setzen.

Dies hat in bestimmten Situationen viele Vorteile. Einige Bereitstellungsmechanismen verlassen sich beispielsweise auf Umgebungsvariablen, um Authentifizierungsinformationen zu konfigurieren. Dies ist nützlich, da es nicht erforderlich ist, diese in Dateien zu halten, die von Außenstehenden gesehen werden können.

Es gibt viele andere, alltäglichere, aber häufigere Szenarien, in denen Sie die Umgebung Ihres Systems auslesen oder ändern müssen. Diese Tools und Techniken sollten Ihnen eine gute Grundlage für die Durchführung dieser Änderungen und die korrekte Verwendung bieten.