Was sind Umgebungsvariablen? (Linux)

Einführung

Zweck dieses Artikels

In Anlehnung an das vorherige [Was ist Standardeingabe / Standardausgabe?](/ Angel_p_57 / items / 03582181e9f7a69f8168) wird versucht, Konzepte und Grundlagen zu erläutern, die für Anfänger von Linux / UNIX möglicherweise schwer zu verstehen sind. Dieses Mal sprechen wir über ** Umgebungsvariablen **. Windows hat den gleichen Begriff, und ich denke, er ist konzeptionell ähnlich, aber es geht nur um Linux / UNIX.

Hinweis

In Bezug auf die Erklärung von Umgebungsvariablen, die Sie häufig sehen, gibt es in diesem Artikel viele Erläuterungen zu deren Verwendung, z. B. "Zum PATH hinzufügen, um Befehle in diesem Verzeichnis auszuführen" oder "Sprache mit LANG festlegen" Darüber rede ich nicht wirklich. Für Standardumgebungsvariablen kann beispielsweise Kapitel POSIX-Standardumgebungsvariablen hilfreich sein (auf Englisch). ).

Was sind Umgebungsvariablen?

Super Übersicht

Einfach ausgedrückt ist eine Umgebungsvariable ** eine Art Parameter zum Anpassen des Verhaltens eines Programms **, der für jeden Prozess beibehalten und verwaltet wird **. Daher ist beim Umgang mit Linux / UNIX die Kenntnis von Umgebungsvariablen nur erforderlich, weil ** es einige Situationen gibt, in denen das Verhalten des Programms durch Umgebungsvariablen angepasst wird **.

Anpassen des Verhaltens des Programms

Übrigens ist der oben erwähnte Begriff "Prozess" ein Begriff, der sich auf die Ausführungseinheit [^ 1] eines Programms auf dem Betriebssystem bezieht. Wie Sie vielleicht wissen, kann unter Linux / UNIX dasselbe Programm viele Male und manchmal gleichzeitig ausgeführt werden, und das von Zeit zu Zeit erzielte Ergebnis variiert je nach Situation [^ 2].

Die Faktoren, die das Ergebnis ändern, sind die Standardeingabe / -ausgabe, die unter [Was ist Standardeingabe / Standardausgabe?](/ Angel_p_57 / items / 03582181e9f7a69f8168) erläutert wird, und je nach Programm können verschiedene Einstellungsdateien beteiligt sein. Nun, es gibt verschiedene Dinge. Es werden jedoch nur ** 2 Arten von Parametern angegeben, wenn das Programm als Betriebssystem ausgeführt wird, mit Ausnahme des Programmdateinamens ** [^ 3]. Eines ist das ** Befehlszeilenargument ** und das andere ist die ** Umgebungsvariable **.

Nur für den Fall, dass das Befehlszeilenargument buchstäblich ** die Befehlszeichenfolge selbst ist, die zum Ausführen des Programms angegeben wurde **, z. B. wenn Sie den Befehl ls -l,` ls ausführen Die Array-Daten [^ 4] werden in zwei Zeichenfolgen "und" -l "zerlegt.

Parameter für jeden Prozess

Da Befehlszeilenargumente und Umgebungsvariablen bei der Ausführung des Programms angegeben werden, werden natürlich ** nicht nur Befehlszeilenargumente, sondern auch Umgebungsvariablen für jeden Prozess verwaltet **.

Vielleicht sind einige Leute neugierig auf Multithread-Programme. Umgebungsvariablen sind innerhalb des Prozesses üblich, dh ** gemeinsam genutzte Daten zwischen Threads **.

Und diese Informationen für jeden Prozess können im Fall von Linux über das proc-Dateisystem referenziert werden.

Angenommen, Sie haben dasselbe Schlafprogramm, in dem zwei Prozesse (PID 63, 64) wie folgt ausgeführt werden:

Status des Schlafbefehls


$ ps -fC sleep
UID        PID  PPID  C STIME TTY          TIME CMD
angel       63     5  0 17:51 pts/0    00:00:00 sleep 300
angel       64     5  0 17:51 pts/0    00:00:00 sleep 600

Zu diesem Zeitpunkt werden die Befehlszeilenargumente jedes Prozesses und die zur Laufzeit angegebenen Umgebungsvariablen ** durch Lesen der Dateien "/ proc / PID / cmdline" und "/ proc / PID / environ" [^ 5] gelesen. Du kannst wissen.

Da das Innere der Datei durch NUL-Zeichen (ASCII-Code 0) getrennt ist, ist das Lesen einfacher, wenn Sie es mit dem Befehl tr in einen Zeilenumbruch ändern. (Sie können überprüfen, ob das NUL-Zeichen mit dem Befehl od verwendet wird.)

Beispiel für das Abrufen von Informationen aus dem Proc-Dateisystem


$ od -An -tc /proc/63/cmdline
   s   l   e   e   p  \0   3   0   0  \0
$ tr \\0 \\n < /proc/63/cmdline
sleep
300
$ tr \\0 \\n < /proc/64/cmdline
sleep
600
$ od -An -tc /proc/63/environ
   P   A   T   H   =   /   b   i   n  \0   H   O   G   E   =   h
   o   g   e  \0
$ tr \\0 \\n < /proc/63/environ
PATH=/bin
HOGE=hoge
$ tr \\0 \\n < /proc/64/environ
PATH=/bin
UGE=uge

Aus diesem Grund verwendet das Schlafprogramm von PID 63 zwei Elemente von "sleep" und "300" als Befehlszeilenzeichenfolgen und zwei Elemente von "PATH = / bin" und "HOGE = hoge" als Umgebungsvariablen und von PID 64. Sie können sehen, dass es mit "sleep", "600" und "PATH = / bin", "UGE = uge" ausgeführt wurde.

Unterschiede zwischen Befehlszeilenargumenten und Umgebungsvariablen

Bisher haben wir erklärt, dass bei der Ausführung eines Programms Befehlszeilenargumente und Umgebungsvariablen als Parameter angegeben werden müssen. All dies dient zur Anpassung des Programmverhaltens. Aber warum gibt es zwei Arten? Der Grund ist nicht klar (da es sich um ein Designproblem als UNIX-Betriebssystem handelt). Aber du kannst es erraten. Wir werden uns dem Unterschied zwischen beiden nähern.

Unterschied im Datenformat

Erstens ist der Unterschied im Datenformat. Ein Auszug eines Beispiels zum Lesen der Dateien "/ proc / PID / cmdline" und "/ proc / PID / environ" wird nachgedruckt.

Auszug aus einem Beispiel zum Abrufen von Informationen aus dem Proc-Dateisystem


$ tr \\0 \\n < /proc/63/cmdline
sleep
300
$ tr \\0 \\n < /proc/63/environ
PATH=/bin
HOGE=hoge

Sie können sehen, dass das Befehlszeilenargument nur aus mehreren Zeichenfolgen besteht, die Umgebungsvariable jedoch eine Sammlung von "Name = Wert" -Paaren [^ 7] ist. Wie Sie sich vorstellen können, gibt es die folgenden Unterschiede zwischen den beiden.

Ein "assoziatives Array" wird in einigen Programmiersprachen als Hash oder Wörterbuch bezeichnet. Mit anderen Worten, wenn die Umgebungsvariable Daten von "HOGE = hoge" enthält, bedeutet dies, dass der Wert von "hoge" dem Schlüssel von "HOGE" zugeordnet ist.

Überraschenderweise gibt es keine besonderen Einschränkungen für die Zeichen, außer dass NUL-Zeichen (ASCII-Code 0) und = nicht als Schlüssel verwendet werden können. Es kann jedoch Probleme beim tatsächlichen Betrieb geben [^ 8], daher ist es sicherer, es auf die alphanumerischen Zeichen und Unterstriche von ASCII-Zeichen zu beschränken. (Es ist üblich, Großbuchstaben zu verwenden)

Übrigens unterscheiden sich der Status, in dem die Umgebungsvariable keinen bestimmten Schlüssel enthält, und der Status, in dem ein Schlüssel vorhanden ist, der Wert jedoch leer ist (Zeichenfolge mit der Länge Null). (Einige Programme behandeln möglicherweise verschiedene Dinge auf die gleiche Weise.) Das Folgende ist ein Beispiel für die Ausführung des Datumsbefehls ohne Schlüssel TZ, der die Zeitzone angibt, und mit einem Schlüssel, aber einem leeren Wert. Der Unterschied besteht darin, dass erstere die Standardzeitzone des Systems und letztere UTC verwendet.

TZ(Zeitzoneninformationen)Unterschied im Datumsverhalten aufgrund von


$ date  #Kein Schlüssel TZ, wenn der Systemstandard JST ist
Sonntag, 2. Dezember 2018 20:35:01 JST
$ TZ= date  #Geben Sie ein leeres Zeichen für die Taste TZ an und behandeln Sie es als UTC
Sonntag, 2. Dezember 2018 11:35:08 UTC
$ date -u #Geben Sie UTC im Befehlszeilenargument an
Sonntag, 2. Dezember 2018 11:35:12 UTC

Übrigens, wie oben erwähnt, ist eine Umgebungsvariable eine Sammlung mehrerer Daten, aber es ist mühsam, etwas wie "den Wert zu sagen, der dem Umgebungsvariablenschlüssel" TZ "zugeordnet ist ...", und niemand tut dies. Daher wird es allgemein als "TZ" -Umgebungsvariable (Wert) bezeichnet, als ob es einzelne Daten gäbe. TZ ist auch ein" Umgebungsvariablenname "und kein" Schlüssel ".

Unterschied in der Verwendung

Als nächstes kommt der Unterschied in der Verwendung zwischen den beiden. Einige von ihnen haben Auswirkungen wie die Umgebungsvariable TZ und das Befehlszeilenargument -u von date, und es ist nicht ungewöhnlich, Umgebungsvariablen und Befehlszeilenargumente zu kombinieren, die genau den gleichen Effekt haben.

Mit anderen Worten, die beiden werden gemäß solchen "Effekten" nicht richtig verwendet. Die ordnungsgemäße Verwendung der beiden erfolgt eher aus administrativen Gründen.

Informationsredundanz

Das Befehlszeilenargument sind Array-Daten, während die Umgebungsvariable ein assoziatives Array ist. Mit anderen Worten, Ersteres hat eine problematische Struktur, die selbst dann sortiert werden kann, wenn unnötige Informationen eingegeben werden, während Letzteres nicht verwendete Schlüssel einfach ignoriert.

Mit anderen Worten, das Befehlszeilenargument ** ist eine Verwendung, die nur die Informationen angibt, die wirklich erforderlich sind **, während die Umgebungsvariable die Redundanz ist, die ** die in verschiedenen Programmen angegebenen Informationen zusammenführt und als maximale Verpflichtung ** angibt. Es kann mit Sex verwendet werden.

Trennung von gemeinsamer Verarbeitung und individueller Verarbeitung

Schauen Sie sich jetzt die Umgebungsvariable TZ an.

Ich habe vorhin ein Beispiel mit dem Befehl "Datum" gegeben, aber tatsächlich ist es auch für verschiedene Programme wirksam, die sich auf Zeitinformationen beziehen, wie z. B. zeitstempelbezogene Dateien von "ls" und "stat".

Auswirkung der TZ-Umgebungsvariablen auf ls


$ ls -l test.txt  #Systemstandard(In diesem Fall JST)Zeitstempelausgabe in
-rwx------1 Engel Engel 398 2. Dezember 20:52 test.txt
$ TZ= ls -l test.txt  #Zeitstempelausgabe an UTC
-rwx------1 Engel Engel 398 2. Dezember 11:52 test.txt

Dies liegt daran, dass die Bibliotheksfunktion localtime, die das Datum / die Stunde / den Tag / die Sekunde aus dem Zeitstempel (UNIX-Zeit [^ 9]) berechnet, ihr Verhalten in Abhängigkeit von der Umgebungsvariablen TZ ändert. Um es anders herum auszudrücken, Programme wie ls kennen diese Umgebungsvariable nicht.

Lassen Sie uns hier darüber nachdenken. Beim Schreiben eines Programms werden selten alle Funktionen von Grund auf neu geschrieben, und für den größten Teil der Verarbeitung sollte eine Art Bibliothek verwendet werden. Was ist, wenn Sie versuchen, alle Bibliotheken anzupassen, die für den Hauptzweck des Programms trivial sind, aber mit Befehlszeilenargumenten ** einstellbar sind? Die Interpretation von Befehlszeilenargumenten kann für sich genommen furchtbar kompliziert sein, und selbst eine kleine Änderung in der Bibliothek kann überwältigend sein.

Daher ist es sinnvoll, die Teile, die sich auf die einzelnen Funktionen des Programms beziehen, durch Befehlszeilenargumente und die allgemeinen Funktionen wie Bibliotheken mit Umgebungsvariablen zu trennen.

In einigen Fällen werden gemeinsame Umgebungsvariablen verwendet, um ähnliche Funktionen mehrerer Programme zu steuern, auch wenn es sich nicht um eine Bibliothek handelt. Die Umgebungsvariable LANG [^ 10], die steuert, welche Sprache verwendet werden soll, Englisch oder Japanisch usw., ist ein typisches Beispiel.

Handhabung und Rolle von Umgebungsvariablen

Daher erklärte ich, dass die Umgebungsvariablen wie folgt verwendet werden können.

Darüber hinaus sind APIs, die die Programmausführung steuern, in Standardbibliotheken und verschiedenen Programmiersprachen häufig so konzipiert, dass sie die Umgebungsvariablen des aktuellen Prozesses an das Programm erben, das sie startet. [^ 11]

Aufgrund der oben genannten Eigenschaften wurden beispielsweise alle Prozesse von ihr gestartet (indem die Umgebungsvariable geerbt wurde) (Programm), sobald die Umgebungsvariable LANG als ja_JP.UTF-8 (japanisches UTF-8) angegeben wurde. Ändern Sie das Verhalten so, dass es auf Japanisch ausgegeben wird (sofern dies unterstützt wird). Da sich verschiedene Programme so verhalten, als ob sie dieselben Parameter verwenden, werden sie ** verwendet, als wären sie globale Einstellungsinformationen, die die Ausführungsumgebung verschiedener Programme steuern.

Aber wir müssen hier vorsichtig sein. Umgebungsvariablen werden einfach Informationen aus dem Startprozess durch das Verhalten "standardmäßig übernehmen" übergeben. ** Das Betriebssystem streut keine allgemeinen Einstellungen mit mysteriöser Kraft **. Wenn Sie sich also mit ssh anmelden, z. B. wenn ein Job mit cron ausgeführt wird, wird beispielsweise eine serverseitige Anwendung von einem Webserver ausgeführt. Zu diesem Zeitpunkt kann der Inhalt der Umgebungsvariablen je nach Startvorgang völlig unterschiedlich sein.

In Bezug auf Umgebungsvariablen ist es daher besser zu wissen, wie und von welchem Programm die Informationen geerbt werden und in welchem Umfang sie beeinflusst werden.

Umgebungsvariablen bearbeiten

Bisher haben wir nur über das Übergeben von Umgebungsvariablen beim Ausführen eines Programms gesprochen, aber Sie können Umgebungsvariablen (Hinzufügen, Löschen von Schlüsseln, Ändern von Schlüsselwerten) auch nach dem Starten des Programms selbst bearbeiten * *.

Im Folgenden werden wir die Funktionsweise von Umgebungsvariablen in jeder Situation untersuchen.

Wer verwaltet Umgebungsvariablen?

Wenn das Programm gestartet wird, empfängt es Umgebungsvariablen vom Betriebssystem, aber die dedizierte C-Sprach-API verwaltet die nachfolgenden Vorgänge. Betriebssystem ist nicht beteiligt.

Die typische API lautet wie folgt.

Beachten Sie, dass ** das Ändern von Umgebungsvariablen nicht threadsicher ist **. In einem Multithread-Programm besteht die Umgebungsvariable selbst aus gemeinsam genutzten Daten zwischen Threads. Wenn Sie also die Konsistenz zwischen Threads bei Änderungen nicht berücksichtigen, kann dies zu Fehlfunktionen führen und unterschiedliche Umgebungsvariablen in verschiedenen Threads verwenden. Du kannst nicht.

Manipulieren Sie Umgebungsvariablen in der Shell usw.

Da die Hauptaufgabe der Shell darin besteht, die Programmausführung zu steuern, halte ich die Manipulation von Umgebungsvariablen in der Shell für die typischste Methode.

Und im Fall der Shell ** können die Umgebungsvariablen durch Erweitern der Shell-Variablen ** behandelt werden.

Bearbeiten von Umgebungsvariablen in der Shell

Insbesondere im Fall von Bash können Sie auf normale Variablen verweisen / diese ändern und Umgebungsvariablen auf dieselbe Weise verweisen / ändern [^ 12]. Ein Unterschied besteht darin, "ob das Attribut einer Umgebungsvariablen hinzugefügt werden soll oder nicht". Mit dem Befehl declare können Sie sehen, ob eine Variable eine reguläre Variable oder eine Umgebungsvariable ist. Dieser Befehl declare kann auch zum Hinzufügen von Umgebungsvariablenattributen verwendet werden. (Obwohl der häufigste Befehl "export" ist)

Beispiel für eine variable Operation


$ declare -p SHELL  #SHELL ist normalerweise eine Umgebungsvariable( -Gesehen von x)
declare -x SHELL="bash"
$ echo $SHELL  # $Kann durch Variablennamen referenziert werden
bash
$ HOGE=hoge  #Wenn Sie einfach eine Variable definieren, ist die Standardeinstellung eine normale Variable
$ declare -p HOGE  # -Da es kein x gibt, kann es als normale Variable verstanden werden
declare -- HOGE="hoge"
$ echo $HOGE  # $Kann durch Variablennamen referenziert werden
hoge
$ declare -x HOGE  #Gewähren von Umgebungsvariablenattributen(Wenn Sie das Attribut löschen möchten+Mach mit x)
$ declare -p HOGE  #Sie können sehen, dass es sich in eine Umgebungsvariable geändert hat
declare -x HOGE="hoge"
$ HOGE=hogehoge    #Sobald das Umgebungsvariablenattribut angehängt ist, bleibt das Attribut auch dann gleich, wenn der Wert geändert wird.
$ declare -p HOGE  #Noch Umgebungsvariablen
declare -x HOGE="hogehoge"
$ UGE=uge; export UGE  #Export führt auch Umgebungsvariablenattribute aus(Die Definition kann mit einem Befehl erfolgen)
$ declare -p UGE  #Sie können sehen, dass es sich um eine Umgebungsvariable handelt
declare -x UGE="uge"
$ unset UGE  #Löschen Sie sowohl reguläre Variablen als auch Umgebungsvariablen
$ declare -p UGE  #Es wird ein Fehler sein, weil es gelöscht wurde
bash: declare: UGE:Nicht gefunden

Die auf diese Weise festgelegten Umgebungsvariablen wirken sich auf das Verhalten der Shell selbst sowie auf die Befehle aus, die von der Shell im Allgemeinen ausgeführt werden.

Wenn Sie alle Informationen der Umgebungsvariablen anzeigen möchten, führen Sie den Befehl declare -x aus, ohne den Variablennamen anzugeben. Alternativ können Sie den Befehl printenv ausführen.

Festlegen temporärer Umgebungsvariablen

Sie können die Umgebungsvariable jedoch vorübergehend festlegen, wenn Sie den Befehl ausführen, oder Sie können den Befehl mit gelöschter Umgebungsvariable ausführen (damit er nicht vererbt werden kann).

Temporäre Variablenänderung


$ declare -p LANG TZ   #LANG ist japanisches UTF, TZ ist keines(Standardzeitzone)
declare -x LANG="ja_JP.UTF-8"
bash: declare: TZ:Nicht gefunden
$ date -d 2018-12-25T00:00+0900
Dienstag, 25. Dezember 2018 00:00:00 JST
$ LANG= TZ=America/Los_Angeles date -d 2018-12-25T00:00+0900 #Vorübergehend SPRACHEN,Stellen Sie TZ ein
Mon Dec 24 07:00:00 PST 2018
$ declare -p LANG TZ   #Die Umgebungsvariablen der Shell selbst haben sich nicht geändert
declare -x LANG="ja_JP.UTF-8"
bash: declare: TZ:Nicht gefunden
$ ( exec -c date -d 2018-12-25T00:00+0900 )  #Wird mit gelöschten Umgebungsvariablen ausgeführt und nicht mehr auf Japanisch ausgegeben
Tue Dec 25 00:00:00 JST 2018
$

Im obigen Beispiel wird der Befehl exec in einer Unterschale mit dem Befehl exec in Klammern ausgeführt, da der Befehl exec bewirkt, dass ** das Programm in Form des Ersetzens der aktuellen Shell ** ausgeführt wird **. .. Die Klammern sind nicht erforderlich, wenn die Shell nicht mehr weiter ausgeführt werden muss. ~~ Wenn Sie alternativ einfach exec -c ohne einen Befehlsnamen in Klammern ausführen, werden die Umgebungsvariablen der laufenden Shell gelöscht. ~~ * Es tut mir leid, diese Beschreibung scheint missverstanden worden zu sein, daher werde ich sie stornieren.

Im Fall von Bash können die temporäre Einstellung von Umgebungsvariablen und die temporäre Löschung jedoch nicht zusammen verwendet werden. Wenn Sie es zusammen verwenden möchten, können Sie den Befehl env verwenden.

Beispiel für einen Befehl env


$ date -d 2018-12-25T00:00+0900  #Rohzustand
Sonntag, 2. Dezember 2018 20:41:02 JST
$ env TZ=America/Los_Angeles date  #Nur TZ-Einstellung
Sonntag, 2. Dezember 2018 03:41:12 PST
$ env - /bin/date  #Umgebungsvariablen löschen und ausführen
Sun Dec  2 20:41:30 JST 2018
$ env - PATH=/bin:/usr/bin TZ=America/Los_Angeles date  #Stellen Sie TZ ein, nachdem Sie Umgebungsvariablen gelöscht haben
Sun Dec  2 03:41:44 PST 2018

Auf diese Weise können Sie die Umgebungsvariablen einfach vorübergehend festlegen, löschen oder beide verwenden. Wenn Sie jedoch die Umgebungsvariable löschen, wird auch die Umgebungsvariable "PATH" gelöscht, sodass die Programmdatei nicht automatisch anhand des Befehlsnamens durchsucht wird. Daher muss der Dateiname wie "/ bin / date" angegeben oder die Umgebungsvariable "PATH" erneut festgelegt werden.

Beispiele für andere Tools

Als weiteres Beispiel werde ich "make" einführen, das die im Tool verwalteten Variablen und die Umgebungsvariablen genau behandelt.

make ist ein Tool, das traditionell zum Erstellen von Programmen verwendet wird (Kompilieren und Verknüpfen von Programmen, die in mehrere Dateien aufgeteilt sind, installieren Sie sie im Systemverzeichnis).

Das Folgende ist ein Beispiel für das Erstellen einer Datei "Makefile", die das Verhalten von "make" steuert und den Inhalt von Variablen und den Inhalt von Umgebungsvariablen über diese Datei ausgibt. Ich kann es mir nicht leisten zu erklären, wie man es benutzt, aber ich hoffe, Sie können sehen, wie es auf ähnliche Weise gehandhabt wird.

Beispiel für die Verwendung von Variablen durch make selbst


$ cat > Makefile   #Erstelle zuerst ein Makefile, Strg-Eingabe mit D beenden
HOGE ?= hoge #Variable Einstellungen(Nur wenn nicht eingestellt)、$(Variablennamen)Sehen in
default:
#Geben Sie den Inhalt der Variablen aus
        @echo $(HOGE)
#Umgebungsvariablen ausgeben(Wenn eingestellt)
        @printenv HOGE
^D
$ make  #Printenv schlägt fehl, weil die Variablen in make keine Umgebungsvariablen sind
hoge
Makefile:4:Ziel'default'Fehler mit dem Rezept
make: *** [default]Fehler 1
$ HOGE=hogehoge make  #Auch wenn es als Umgebungsvariable festgelegt ist, wird es wie eine Variable behandelt
hogehoge
hogehoge
$ make HOGE=hogehoge  #Wird als Umgebungsvariable festgelegt, wenn sie als Befehlszeilenargument angegeben wird
hogehoge
hogehoge

Bearbeiten Sie Umgebungsvariablen in der Skriptsprache

Als nächstes werde ich darauf eingehen, wie Umgebungsvariablen in verschiedenen Skriptsprachen (Perl, Python, Ruby) bearbeitet werden.

In diesen Sprachen können Sie Umgebungsvariablen so bearbeiten, als würden Sie assoziative Arrays (Wörterbücher / Hashes) bearbeiten. Für Perl ist es "% ENV", für Python ist es das Betriebssystem "os.environ" und für Ruby ist es "ENV".

Dies sind nicht nur Variablen, sondern spezielle Daten, die C-Sprach-APIs wie "getenv" und "putenv" durch Operationen ausführen.

Unten finden Sie die Skripte, mit denen die Umgebungsvariable "TZ" festgelegt und in der Anzeige der aktuellen Uhrzeit angezeigt wird.

date.pl


use POSIX;

print strftime("%c",localtime),"\n";
$ENV{TZ}="America/Los_Angeles";
print strftime("%c",localtime),"\n";

date.py


import datetime
import os

print(datetime.datetime.now().strftime("%c"))
os.environ["TZ"]="America/Los_Angeles"
print(datetime.datetime.now().strftime("%c"))

date.rb


puts Time.now.strftime("%c")
ENV["TZ"]="America/Los_Angeles"
puts Time.now.strftime("%c")

Sie geben dasselbe Ausgabeformat mit derselben "strftime" -API an. Sie können sehen, dass die Zeitzone vor und nach dem Ändern der Umgebungsvariablen eine Zeitverzögerung aufweist.

Ausführung jedes Skripts


$ unset LANG
$ perl date.pl
Sun Dec  2 18:47:35 2018
Sun Dec  2 01:47:35 2018
$ python3 date.py
Sun Dec  2 18:47:40 2018
Sun Dec  2 01:47:40 2018
$ ruby date.rb
Sun Dec  2 18:47:44 2018
Sun Dec  2 01:47:44 2018

Vorsichtsmaßnahmen für den Betrieb mit Umgebungsvariablen

Es gibt eine Einschränkung beim Bearbeiten von Umgebungsvariablen während der Programmausführung.

Das heißt, ** das Ändern einer Umgebungsvariablen hat nicht immer unmittelbare Auswirkungen **. Dies liegt daran, dass einige Bibliotheken die Umgebungsvariablen nur beim Starten des Programms betrachten und die Initialisierungsverarbeitung durchführen. Danach werden die Änderungen in den Umgebungsvariablen möglicherweise nicht mehr verfolgt.

Tatsächlich hat auch die Umgebungsvariable "LANG", die die Sprache anpasst, einen solchen Aspekt. Wie im folgenden Perl-Beispiel wird nach dem Ändern der Umgebungsvariablen die Änderung nicht wiedergegeben, wenn Sie "POSIX :: setlocale" nicht explizit aufrufen [^ 13].

Reflexion von LANG in Perl


$ #Wenn LANG von Anfang an eingestellt ist, wird es auf Japanisch ausgegeben
$ LANG=ja_JP.UTF-8 perl -CO -MPOSIX -E 'say strftime("%c",localtime)'
02. Dezember 2018 19:55:54
$ #Nur das Ändern von LANG nach dem Start macht es nicht japanisch
$ LANG=C perl -CO -MPOSIX -E '$ENV{LANG}="ja_JP.UTF-8"; say strftime("%c",localtime)'
Tue Dec  2 19:56:21 2018
$ #LANG-Änderungen werden von setlocale wiedergegeben
$ LANG=C perl -CO -MPOSIX -E '$ENV{LANG}="ja_JP.UTF-8"; setlocale(LC_ALL,""); say strftime("%c",localtime)'
02. Dezember 2018 19:56:34

Wenn es sich um eine Umgebungsvariable handelt, die von einem anderen auszuführenden Programm geerbt werden soll, müssen Sie sich dessen nicht sehr bewusst sein. Wenn Sie jedoch das Verhalten Ihres eigenen Prozesses ändern möchten, sollten Sie vorsichtig sein, wenn sich die Änderung dieser Umgebungsvariablen in der Bibliothek widerspiegelt. Ich finde das gut

abschließend

Zusammenfassung

Das ist die Zusammenfassung.

[^ 1]: ** Prozess **: Sie können nach ps oder top Befehl auflisten, aber sie unterscheiden sich durch die ID PID. Das ist es. [^ 2]: ** Einige Dinge wie der Befehl / bin / true liefern immer das gleiche Ergebnis, es sei denn, es liegt ein systematischer Fehler vor, aber diese Befehle sind nicht nützlich. [^ 3]: ** Bei der Ausführung des Programms anzugebende Parameter **: Einzelheiten finden Sie in der Manpage exeve (2). .html). execve ist eine OS-API (Systemaufruf), die Programme ausführt. [^ 4]: ** Zerlegte Sequenzdaten **: Natürlich gibt der Benutzer in der Shell den Befehl als eine Zeichenfolge ein, aber er wird zerlegt und als Sequenzinformation an das Betriebssystem übergeben. ist. [^ 5]: ** Datei lesen **: Das Befehlszeilenargument / proc / PID / cmdline kann von jedem gelesen werden, aber die Umgebungsvariable / proc / PID / environ ist der Prozessausführer oder Es kann nur von root gelesen werden. [^ 6]: ** Nicht reflektiert **: Um die Wahrheit zu sagen, gibt es keine Möglichkeit, den Inhalt später zu ändern, aber ich werde ihn weglassen. [^ 7]: ** Name = Wert-Paar **: Es ist möglich, Daten in einem Format zu übergeben, das nicht name = value ist (das Betriebssystem übergibt nur die angegebenen Daten). Es ist jedoch unklar, welche Auswirkungen dies haben wird, und möglicherweise kann keine Garantie erhalten werden. [^ 8]: ** Mögliche Probleme **: Einfach ausgedrückt, diese Umgebungsvariablen können nicht mehr in der Shell bearbeitet werden. [^ 9]: ** UNIX-Zeit **: UNIX-Zeit ist die Zeit, die durch die Anzahl der Sekunden verwaltet wird, die seit 1970/1/1 00:00 vergangen sind und als Epoche bezeichnet werden. [^ 10]: ** LANG-Umgebungsvariable **: Die LANG-Umgebungsvariable ist jedoch wichtig, da sie die Spracheinstellung durch die Bibliotheksfunktion setlocale beeinflusst, sodass sie möglicherweise mehr für die Bibliothek gilt. Überhaupt nicht. [^ 11]: ** Standardbibliothek zur Ausführung **: Anwendbar ist die sogenannte exec-Familie von Bibliotheksfunktionen. Weitere Informationen finden Sie in der Manpage exec (3). Natürlich gibt es APIs (execle, execvpe), die Umgebungsvariablen angeben können, aber andere APIs zeigen das Verhalten beim Erben von Umgebungsvariablen. [^ 12]: ** Erweiterung normaler Variablen **: Bei csh / tcsh ist die Schnittstelle zum Einstellen und Ändern getrennt (Befehle "setenv", "unsetenv" für Umgebungsvariablen). Es ist jedoch ähnlich wie bei bash, dass Sie mit "$ variable name" auf den Inhalt verweisen können. [^ 13]: ** Wird nicht wiedergegeben, es sei denn, setlocale wird aufgerufen **: Umgekehrt kann gesagt werden, dass die Sprache automatisch festgelegt wird, indem "setlocale" nur beim Starten des Programms aufgerufen wird. Wenn sich die Verarbeitung jedoch nicht auf "setlocale" bezieht, während die Umgebungsvariable "LANG" betroffen ist, kann sie sofort betroffen sein. Wenn Sie nicht daran denken, Umgebungsvariablen an andere Programme zu erben, ist es schneller, die Sprache direkt mit setlocale anzugeben, ohne die Umgebungsvariablen LANG zurückzusetzen.

Recommended Posts

Was sind Umgebungsvariablen? (Linux)
Aufbau einer Linux-Umgebung
Was ist Linux?
Was ist Linux?
Shell-Variablen, Umgebungsvariablen
Was sind Linux POSIX Option und GNU Option?
Was ist Linux?
Was ist Linux?
Ich wusste nicht viel über Linux-Umgebungsvariablen
Linux PATH-Umgebungsvariable
Wofür ist Linux?
Was ist UNIT-V Linux?
Umgebungsvariablen bei Verwendung von Tkinter
Informationen zum Aufbau einer Linux-Umgebung (CentOS)
Handle Go-Umgebungsvariablen (Viper)
SSH-Einschränkungen in der Linux-Umgebung
Erste LAMP-Umgebungskonstruktion (Linux)
Behandeln Sie Umgebungsvariablen in Python
HTTP-Umgebungsvariablen in Flask
Was ich über Linux gelernt habe
Ablauf, in dem Malloc-Parameter aus Umgebungsvariablen festgelegt werden
Aufbau einer Linux-Umgebung (in einer WSL-Umgebung)
Umgebungsvariablen mit Lambda-Uploader einstellen
Was sind die Verzeichnisse wie Linux, / etc und / var / log?
Bereiten Sie die Pipenv-Umgebung mit Amazon Linux 2 vor
Informationen zum Aufbau einer Linux-Umgebung (VMware Virtual BOX)
[Python] Was sind @classmethod und Dekorateure?
(Anfänger) Was sind Kerne und Threads?
Erstellen Sie eine Linux-Umgebung unter Windows 10
Versuchen Sie, AWS Lambda-Umgebungsvariablen anzugeben?
[Linux] Aufbau einer Docker-Umgebung auf Redhat
Führen Sie die Python 3.5.2-Umgebung unter Amazon Linux ein
Lesen Sie Systemumgebungsvariablen mit Python-Teil 1
Lesen Sie Systemumgebungsvariablen mit Python-Teil 2