Когда использовать точку с запятой между переменными среды и командой

14

Может кто-нибудь объяснить, почему точка с запятой необходима для того, LANGчтобы bash видел ее обновленной?

Не работает:

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

Работает:

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

Я работаю с Bash 4.1.10 на Linux и той же версии под Cygwin

Ричард Корден
источник

Ответы:

23

Параметр и другие типы расширений выполняются при чтении команды перед ее выполнением.

Первая версия, LANG=Ja_JP bash -c "echo $LANG"это отдельная команда. После того, как он проанализирован как таковой, $LANGон расширяется до того, en_USкак что-либо выполнено. По bashзавершении обработки ввода он разветвляется, добавляет LANG=Ja_JPв среду, как ожидалось, и затем выполняет bash -c echo en_US.

Вы можете предотвратить расширение с помощью одинарных кавычек, то есть LANG=Ja_JP bash -c 'echo $LANG'выходов Ja_JP.

Обратите внимание, что когда у вас есть переменное назначение как часть команды, назначение влияет только на среду этой команды, а не на оболочку.

Вторая версия LANG=Ja_JP; bash -c "echo $LANG"- это две отдельные команды, выполняемые последовательно. Первый - это простое присвоение переменной без команды, поэтому оно влияет на вашу текущую оболочку.

Таким образом, ваши два фрагмента принципиально отличаются, несмотря на поверхностное различие одного ;.

Совершенно не по теме, но я мог бы рекомендовать добавить .UTF-8при настройке LANG. В настоящее время нет веской причины не использовать Unicode в 21-м веке.

jw013
источник
Отличный ответ - спасибо! По поводу добавления UTF-8. Я пытаюсь протестировать обработку языка приложения, которое должно работать на нескольких платформах, некоторые из которых довольно старые. Между такими различиями (которые, к счастью, вы объяснили) и различиями в Linux и Cygwin я собираюсь броситься под автобус!
Ричард Корден
5

VAR=value; somecommand эквивалентно

VAR=value
somecommand

Это несвязанные команды, выполняемые одна за другой. Первая команда присваивает значение переменной оболочки VAR. Если VARэто не переменная среды, она не экспортируется в среду, а остается внутренней для оболочки. Заявление export VARбудет экспортировать VARв окружающую среду.

VAR=value somecommandэто другой синтаксис. Назначение VAR=valueотносится к среде, но это назначение выполняется только в среде выполнения somecommand, а не для последующего выполнения оболочки.

В качестве примера:

# 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
Жиль "ТАК - перестань быть злым"
источник
Я действительно не думал о разнице между переменной оболочки и оболочки. Я должен пойти и сделать некоторые исследования. Спасибо за ответ.
Ричард Корден