Wann ein Semikolon zwischen Umgebungsvariablen und einem Befehl verwendet werden soll

14

Kann jemand erklären, warum das Semikolon notwendig ist, damit das LANGvon bash als aktualisiert angesehen wird?

Funktioniert nicht:

> LANG=Ja_JP bash -c "echo $LANG"
en_US

Werke:

> LANG=Ja_JP ; bash -c "echo $LANG"
Ja_JP

Ich arbeite mit Bash 4.1.10 unter Linux und der gleichen Version unter Cygwin

Richard Corden
quelle

Antworten:

23

Parameter und andere Arten von Erweiterungen werden ausgeführt, wenn der Befehl gelesen wird, bevor er ausgeführt wird.

Die erste Version LANG=Ja_JP bash -c "echo $LANG"ist ein einzelner Befehl. Nachdem es als solches analysiert wurde, $LANGwird es erweitert, en_USbevor etwas ausgeführt wird. Sobald bashdie Verarbeitung der Eingabe abgeschlossen ist, wird ein Prozess abgefragt LANG=Ja_JP, der Umgebung wie erwartet hinzugefügt und anschließend ausgeführt bash -c echo en_US.

Sie können die Erweiterung mit einfachen Anführungszeichen, dh LANG=Ja_JP bash -c 'echo $LANG'Ausgaben, verhindern Ja_JP.

Beachten Sie, dass sich die Zuweisung nur auf die Umgebung dieses Befehls und nicht auf die Umgebung Ihrer Shell auswirkt, wenn Sie eine Variablenzuweisung als Teil eines Befehls haben.

Die zweite Version LANG=Ja_JP; bash -c "echo $LANG"besteht eigentlich aus zwei separaten Befehlen, die nacheinander ausgeführt werden. Die erste ist eine einfache Variablenzuweisung ohne Befehl. Sie wirkt sich also auf Ihre aktuelle Shell aus.

Daher unterscheiden sich Ihre beiden Ausschnitte trotz der oberflächlichen Unterscheidung eines einzelnen grundlegend ; .

Völlig themenfremd, aber möglicherweise empfehle ich, .UTF-8beim Einstellen ein anzuhängen LANG. Es gibt heutzutage keinen guten Grund, Unicode im 21. Jahrhundert nicht zu verwenden.

jw013
quelle
Tolle Antwort - danke! In Bezug auf die Zugabe von UTF-8. Ich versuche, das Gebietsschema-Handling einer Anwendung zu testen, die auf mehreren Plattformen funktionieren muss, von denen einige ziemlich alt sind. Zwischen Unterschieden wie diesem (was Sie zum Glück erklärt haben) und Unterschieden unter Linux und Cygwin werde ich mich gleich unter einen Bus werfen!
Richard Corden
5

VAR=value; somecommand ist äquivalent zu

VAR=value
somecommand

Hierbei handelt es sich um nicht zusammenhängende Befehle, die nacheinander ausgeführt werden. Der erste Befehl weist der Shell-Variablen einen Wert zu VAR. Sofern VARes sich nicht bereits um eine Umgebungsvariable handelt, wird sie nicht in die Umgebung exportiert, sondern verbleibt in der Shell. Eine Anweisung export VARwürde exportierenVAR in die Umgebung .

VAR=value somecommandist eine andere Syntax. Die ZuordnungVAR=value erfolgt zur Umgebung, diese Zuordnung erfolgt jedoch nur in der Ausführungsumgebung von somecommand, nicht für die spätere 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
Gilles 'SO - hör auf böse zu sein'
quelle
Ich hatte nicht wirklich über den Unterschied zwischen einer Shell- und einer Umgebungsvariablen nachgedacht. Ich muss ein bisschen recherchieren. Danke für die Antwort.
Richard Corden