
Kann jemand erklären, warum das Semikolon notwendig ist, damit es LANG
von Bash als aktualisiert angezeigt wird?
Funktioniert nicht:
> LANG=Ja_JP bash -c "echo $LANG"
en_US
Werke:
> LANG=Ja_JP ; bash -c "echo $LANG"
Ja_JP
Ich arbeite sowohl mit Bash 4.1.10 unter Linux als auch mit der gleichen Version unter Cygwin
Antwort1
Parameter- und andere Erweiterungen werden beim Lesen des Befehls durchgeführt,Vores wird ausgeführt.
Die erste Version, LANG=Ja_JP bash -c "echo $LANG"
, ist ein einzelner Befehl. Nachdem er als solcher analysiert wurde, $LANG
wird er zu erweitert, en_US
bevor irgendetwas ausgeführt wird. Sobald bash
die Verarbeitung der Eingabe abgeschlossen ist, verzweigt er einen Prozess, fügt ihn LANG=Ja_JP
wie erwartet zur Umgebung hinzu und führt dann aus bash -c echo en_US
.
Sie können die Erweiterung mit einfachen Anführungszeichen verhindern, d. h. es LANG=Ja_JP bash -c 'echo $LANG'
werden Ausgaben ausgegeben Ja_JP
.
Beachten Sie, dass sich eine Variablenzuweisung als Teil eines Befehls nur auf die Umgebung dieses Befehls auswirkt, nicht jedoch auf die Ihrer Shell.
Bei der zweiten Version LANG=Ja_JP; bash -c "echo $LANG"
handelt es sich eigentlich um zwei separate Befehle, die nacheinander ausgeführt werden. Der erste ist eine einfache Variablenzuweisung ohne Befehl und wirkt sich daher auf Ihre aktuelle Shell aus.
Daher unterscheiden sich Ihre beiden Snippets trotz des oberflächlichen Unterschieds eines einzelnen grundlegend ;
.
Völlig abseits des Themas, aber ich würde empfehlen, eine .UTF-8
„when“-Einstellung anzuhängen LANG
. Es gibt heutzutage keinen guten Grund, Unicode nicht zu verwenden.
Antwort2
VAR=value; somecommand
ist äquivalent zu
VAR=value
somecommand
Dies sind unabhängige Befehle, die nacheinander ausgeführt werden. Der erste Befehl weist der Shell-Variable einen Wert zu VAR
. Sofern VAR
es sich nicht bereits um eine Umgebungsvariable handelt, wird sie nicht in die Umgebung exportiert, sondern bleibt intern in der Shell. Eine Anweisung export VAR
würde in die Umgebung exportieren VAR
.
VAR=value somecommand
ist eine andere Syntax. Die Zuweisung VAR=value
erfolgt an die Umgebung, aber diese Zuweisung wird nur in der Ausführungsumgebung von vorgenommen somecommand
, nicht für die nachfolgende Ausführung der Shell.
Als Beispiel:
# Assume neither VAR1 nor VAR2 is in the environment
VAR1=value
echo $VAR1 # displays "value"
env | grep '^VAR1=' # displays nothing
VAR2=value env | grep '^VAR2=' # displays "VAR2=value"
echo $VAR2 # displays nothing
Antwort3
Dies ist die Zusammenfassung meiner Rechercheergebnisse:
Es gibt zwei Typen: Umgebungsvariablen und Shellvariablen.
Eine Umgebungsvariable ist in einem Programm und seinen untergeordneten Programmen/Prozessen/Sub-Shells verfügbar. Eine Shell-Variable ist nur in der aktuellen Shell verfügbar.
https://askubuntu.com/a/26322/326584
Wie echo $VAR
funktioniert es?
Immer wenn ein Terminal/eine Shell/eine Bash das Symbol $ sieht, führt es etwas aus, das als „Parametererweiterung“ bezeichnet wird. Das bedeutet, dass Variablen durch Werte ersetzt werden.
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
Wenn also VAR
der Wert „Hallo“ war, echo $VAR
wird daraus echo 'hello'
.
was bedeutet, dass dies funktioniert ...
TEST=123
echo $TEST
// 123
aber das Folgende funktioniert nicht, weil die Variable ersetzt wurde, BEVOR der Befehl die Variable festlegen konnte.
TEST2=999 echo $TEST2
// nothing...
aber wenn Sie das Semikolon hinzufügen...
TEST2=999; echo $TEST2
es ist dasselbe wie..
TEST2=999
echo $TEST2
.. das funktioniert genauso wie zuvor.
Und da Shell-Variablen nicht an Unterprozesse/untergeordnete Prozesse übergeben werden, wird beim Aufrufen eines Befehls ein neuer Prozess erstellt, also ...
TEST3=111
node -e 'console.log(process.env.TEST3)'
oder
TEST3=111
printenv TEST3
beide geben nichts aus. Shell-Variablen werden nicht von untergeordneten Prozessen übernommen. Verwenden Sie „export“, um aus einer Shell-Variable eine Umgebungsvariable zu machen.
export TEST3=111
printenv TEST3
//111
Es gibt eine Ausnahme …
VAR=123 printenv VAR
VAR=123 VAR2=456 printenv VAR2 //even multiple vars
Wenn man es so schreibt und direkt nach dem Aufruf des Befehls, legt es grundsätzlich nur vorübergehend die Umgebungsvariable für diesen Befehl fest. Es legt nicht einmal die Shellvariable fest. Betrachten Sie es als eine völlig neue Syntax.
VAR=123 printenv VAR // 123
echo $VAR // nothing
VAR=123
echo $VAR // 123