Параметр и другие типы расширений выполняются при чтении команды перед ее выполнением.
Первая версия, 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-м веке.
Отличный ответ - спасибо! По поводу добавления 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
VAR=value; somecommand
эквивалентноЭто несвязанные команды, выполняемые одна за другой. Первая команда присваивает значение переменной оболочки
VAR
. ЕслиVAR
это не переменная среды, она не экспортируется в среду, а остается внутренней для оболочки. Заявлениеexport VAR
будет экспортироватьVAR
в окружающую среду.VAR=value somecommand
это другой синтаксис. НазначениеVAR=value
относится к среде, но это назначение выполняется только в среде выполненияsomecommand
, а не для последующего выполнения оболочки.В качестве примера:
источник