Wie zeige ich den aktuellen Wert einer Umgebungsvariablen an?


23

Wenn ich die Umgebung meines Systems überprüfe, werden viele Umgebungsvariablen angezeigt. Wie kann ich nur nach einer bestimmten Variablen suchen?

Ein Buch, das ich lese, sagt:

Manchmal wächst die Anzahl der Variablen in Ihrer Umgebung so stark an, dass Sie nicht alle angezeigten Werte sehen möchten, wenn Sie nur an einer interessiert sind. In diesem Fall können Sie den echoBefehl verwenden, um den aktuellen Wert einer Umgebungsvariablen anzuzeigen.

Wie mache ich das in einem Linux-Terminal?

Antworten:


24

Gerade:

echo "$VARIABLENAME"

$HOMEVerwenden Sie für die Umgebungsvariable beispielsweise Folgendes :

echo "$HOME"

Was dann etwas ähnliches ausgibt wie:

/home/username

Edit : Nach dem Kommentar von Stéphane Chazelas kann es besser sein, wenn Sie verwendenprintenv anstelle von echo:

printenv HOME

4
Sie haben die Anführungszeichen vergessen (es sei denn, Sie setzen die Syntax zsh oder rc / es voraus). echoist eine schlechte Wahl eines Befehls, da er den Inhalt der Variablen transformieren könnte. Der Inhalt des Shell-Parameters wird mit demselben Namen ausgegeben. Das ist nicht unbedingt das gleiche , wenn die Bourne - Shell oder für env mit vars wie 1, *zum Beispiel. Und Sie können diesen Ansatz nicht für Umgebungsvariablen verwenden, deren Name nicht als Shell-Variablenname gültig ist.
Stéphane Chazelas

5
Beachten Sie auch, dass, wenn mehrere Umgebungseinträge mit demselben Namen vorhanden sind (OK, ein pathologischer Fall), der von der Shell abhängt (normalerweise entweder der erste oder der letzte). printenv VARzeigt sie alle an (zumindest für die GNU-Implementierung).
Stéphane Chazelas


5

Es ist wichtig zu verstehen, dass jeder Prozess seine eigenen Umgebungsvariablen hat.

Wenn ein Prozess ruft den fork()Systemaufruf, einen zweiten Prozess (das Kind ) identisch mit der ersten ( der Mutter ) erstellt (diese Kopie die Umgebung umfasst, die knapp über dem Stapel befindet (oder knapp darunter, je nachdem , wie Sie von Stapeln denken :-)- aber in unix / linux wächst der stack runter von hohen Adressen ab.

Normalerweise ruft der untergeordnete Prozess dann den execve()Systemaufruf auf, der alles in seinem (virtuellen) Speicher verwirft und rekonstruiert aus den Code- und Datenabschnitten in der angegebenen Binärdatei .

Bei der Rekonstruktion des Stapels werden jedoch die execve()an den Stapel übergebenen Umgebungs- und Argumentzeichenfolgen zuerst (in dieser Reihenfolge) kopiert , bevor die main()Funktion aufgerufen wird (ein Großteil der Arbeit wird im crt0Bootstrap-Code nach der execve()Rückkehr (zum Eintrag) erledigt Punkt in der Binär)) angegeben.

Es gibt Wrapper für den execve()Systemaufruf in der C-Bibliothek, die die aktuelle Umgebung (dh eine Kopie der übergeordneten Umgebung) übergeben, anstatt dass der Aufrufer sie bereitstellt (so dass das Kind in der Tat die übergeordnete Umgebung erbt ) - sieheenviron(7) .

Versuchen Sie, den Befehl (als root) auszuführen ps axeww | less. Dies zeigt Ihnen die Umgebung für alle Prozesse! Ein interessanter Prozess ist Prozess-ID 1 (dh der initProzess - der erste Prozess, der vom Kernel beim Booten erstellt wird).

Wenn Sie die Umgebung nach einem bestimmten Prozess durchsuchen möchten (und wissen, dass es sich um eine Prozess-ID handelt), führen Sie den Befehl aus cat /proc/<PID>/environ(ersetzen)<PID> durch die Prozess-ID).

Beachten Sie, dass ein Prozess, der über genügend Berechtigungen verfügt, seinen eigenen Stapel neu schreiben kann, wodurch es schwierig wird, die Umgebung zu kennen. In der Ausgabe von ps werden einige Dämonprozesse wie diese angezeigt.

Aber am Ende läuft diese ganze Waffel auf das hinaus, was @chaos oben gesagt hat. Wenn Sie den aktuellen Wert einer bestimmten Umgebungsvariablen in Ihrem Shell-Prozess anzeigen möchten, verwenden Sie einfach den Befehl echo "$<NAME>"( builtin) (durch <NAME>den Namen des Befehls ersetzen ) Umgebungsvariable, an der Sie interessiert sind) ... beachten Sie nur, dass dieselbe Variable in einem anderen Prozess möglicherweise einen anderen Wert hat oder überhaupt nicht existiert.


1
(1) Beachten Sie, dass die eOption psund die /proc/…/environspezielle Datei möglicherweise nicht auf allen Systemen vorhanden sind. (2) AFAIK, jeder Unix-Prozess hat das Recht, seinen Stack neu zu schreiben und seine Umgebungsvariablen zu ändern. (3) Weitere Informationen finden Sie unter Wem gehören Umgebungsvariablen? (auf Super User ).
G-Man sagt, dass Monica

Ich hatte es in meinem Kopf , dass einige Systeme einen Weg hatte einen unprivilegierten Prozess von „versteckt“ seine Befehlszeilenargumente und Umgebung zB von root am Laufen zu verhindern ps... aber jetzt , dass Sie diesen Punkt hervorgehoben habe, kann ich erinnere mich nicht , warum ich dachte daß.
Murray Jensen

@MurrayJensen Laut einer Diskussion über die häufig gestellte Frage, die ich zum Thema "Locke" gestellt habe, ist es in POSIX nicht spezifiziert, ob ps die Args zurückgibt, die ursprünglich an den Prozess übergeben wurden, oder eine Kopie, die der Prozess möglicherweise danach geändert hat begann. Einige Systeme (ich denke Solaris ??) zeigen die ursprünglichen Argumente, egal was passiert. (Hier ist der Link.) Möglicherweise haben Sie daran gedacht. :)
Wildcard

Bingo! Ja, natürlich macht Solaris das "richtig" :-) Danke für die Auffrischung ...
Murray Jensen

1

Sie können bekommen, wonach Sie suchen mit export:

export | grep HOME

Zeigt den Inhalt der $HOMEVariablen an.


1

wenn Sie viele Variablen einstellen müssen:

  ( set -o posix ; set ) | sort >~/vars.before

nachdem sie gesetzt haben:

  ( set -o posix ; set ) | sort >~/vars.after

als anzeigen was eingestellt wurde:

  comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'

Auf diese Weise werden Sie bald mit mehreren in cnf-Dateien vordefinierten Sätzen von Shell-Vars arbeiten, die Sie in Kombination mit tmux zum Meister des Konfigurationsmanagements in Shell-Umgebungen machen:

  # ---------------------------------------------------------
  # cat cnf/qto.dev.host-name.cnf
  # [MainSection]
  # postgres_db_name     = dev_qto
  # postgres_db_host     = host-name
  #
  # call by: doParseCnfEnvVars cnf/qto.dev.host-name.cnf
  # ---------------------------------------------------------
  doParseCnfEnvVars(){

     cnf_file=$1;shift 1;
     test -z "$cnf_file" && echo " you should set the cnf_file !!!"

     INI_SECTION=MainSection

     ( set -o posix ; set ) | sort >~/vars.before

     eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
        -e 's/#.*$//' \
        -e 's/[[:space:]]*$//' \
        -e 's/^[[:space:]]*//' \
        -e "s/^\(.*\)=\([^\"']*\)$/export \1=\"\2\"/" \
        < $cnf_file \
        | sed -n -e "/^\[$INI_SECTION\]/,/^\s*\[/{/^[^#].*\=.*/p;}"`

     # and post-register for nice logging
     ( set -o posix ; set ) | sort >~/vars.after

     echo "INFO added the following vars from section: [$INI_SECTION]"
     comm -3 ~/vars.before ~/vars.after | perl -ne 's#\s+##g;print "\n $_ "'
  }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.