Kiedy używać średnika między zmiennymi środowiskowymi a poleceniem

14

Czy ktoś może wyjaśnić, dlaczego średnik jest niezbędny, LANGaby był postrzegany jako zaktualizowany przez bash?

Nie działa:

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

Pracuje:

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

Pracuję zarówno z bash 4.1.10 na Linuksie, jak i tą samą wersją pod cygwin

Richard Corden
źródło

Odpowiedzi:

23

Parametry i inne typy rozszerzeń są wykonywane podczas odczytywania polecenia przed jego wykonaniem.

Pierwsza wersja LANG=Ja_JP bash -c "echo $LANG", to jedno polecenie. Po przeanalizowaniu jako taki $LANGjest rozwijany do, en_USzanim cokolwiek zostanie wykonane. Po bashzakończeniu przetwarzania danych wejściowych, forksuje proces, dodaje LANG=Ja_JPdo środowiska zgodnie z oczekiwaniami, a następnie wykonuje bash -c echo en_US.

Możesz zapobiec ekspansji za pomocą pojedynczych cudzysłowów, tj . LANG=Ja_JP bash -c 'echo $LANG'Wyników Ja_JP.

Zauważ, że gdy masz przypisanie zmiennej jako część polecenia, przypisanie wpływa tylko na środowisko tego polecenia, a nie na środowisko twojej powłoki.

Druga wersja LANG=Ja_JP; bash -c "echo $LANG"to tak naprawdę dwa osobne polecenia wykonywane po kolei. Pierwszy to proste przypisanie zmiennej bez polecenia, więc wpływa na twoją bieżącą powłokę.

Zatem dwa fragmenty są zasadniczo różne pomimo powierzchownego rozróżnienia jednego ;.

Zupełnie nie na temat, ale mogę polecić dodanie .UTF-8ustawienia LANG. Nie ma obecnie żadnego powodu, aby nie używać Unicode w XXI wieku.

jw013
źródło
Świetna odpowiedź - dzięki! Odnośnie dodania UTF-8. Próbuję przetestować obsługę ustawień regionalnych aplikacji, która musi działać na kilku platformach, z których niektóre są dość stare. Między różnicami takimi jak ta (którą na szczęście wyjaśniłeś) a różnicami na Linuksie i Cygwinie, zamierzam rzucić się pod autobus!
Richard Corden,
5

VAR=value; somecommand jest równa

VAR=value
somecommand

Są to niepowiązane polecenia wykonywane jeden po drugim. Pierwsze polecenie przypisuje wartość do zmiennej powłoki VAR. Jeśli nie VARjest już zmienną środowiskową, nie jest eksportowana do środowiska, pozostaje wewnętrzną powłoką. Instrukcja export VARwyeksportuje VARsię do środowiska.

VAR=value somecommandto inna składnia. Przypisanie VAR=valuedotyczy środowiska, ale to przypisanie jest wykonywane tylko w środowisku wykonawczym somecommand, a nie w celu późniejszego wykonania powłoki.

Na przykład:

# 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- przestań być zły”
źródło
Tak naprawdę nie myślałem o różnicy między zmienną środowiskową shell a shell. Będę musiał przeprowadzić badania. Dziękuję za odpowiedź.
Richard Corden,