Почему «A = 10 echo $ A» не печатает 10?

Эта команда:

A=10 echo $A

печатает пустую строку. Почему нет 10? Почему не работает временная настройка среды?

Я хочу знать причину и объяснение, а не решение.

Я использовал

LANG=C gcc ...

, чтобы заставить gcc использовать запасной язык (английский) вместо системного (китайский). Поэтому я предполагаю, что префикс VAR=value настроит временную среду для следующей за ним команды. Но, похоже, у меня какое-то недопонимание.

25
задан 29 May 2014 в 14:48

3 ответа

Это - вопрос порядка, в котором происходят различные шаги оценки команды.

A=10 echo $A первые синтаксические анализы команда в простую команду сделаны из трех слов A=10, echo и $A. Затем каждое слово подвергается подстановке переменных, т.е. преобразованию переменных расширений такой как $A в их значения (я опускаю шаги, которые не делают ничего видимого).

Если A имеет значение foo первоначально, результатом шагов расширения является простая команда, которая все еще имеет три слова: A=10, echo и foo. (Оболочка также помнит в этой точке, которой символы были первоначально в кавычках — в этом случае, ни один.) Следующий шаг должен выполнить команду. С тех пор A=10 начинается с допустимого имени переменной, сопровождаемого знаком "равно", это рассматривают как присвоение; переменная A установлен на 10 и в оболочке и в среде во время выполнения команды. (Обычно необходимо записать export A иметь A в среде и не так же, как переменная оболочки; это - исключение.) Следующее слово не является присвоением, таким образом, его рассматривают как название команды (это - встроенная команда). echo команда не зависит ни от какой переменной, таким образом, A=10 echo $A имеет точно тот же эффект как echo $A.

Если Вы хотите установить переменную на время команды только, но принятие во внимание присвоения при выполнении команды, можно использовать подоболочку. Подоболочка, обозначенная круглыми скобками, вносит все изменения состояния (переменные присвоения, текущий каталог, функциональные определения, и т.д.) локальный для подоболочки.

(A=10; echo $A)

Сделайте это export A=10 если Вы хотите экспортировать переменную в среду так, чтобы она была замечена внешними программами.

22
ответ дан 29 May 2014 в 14:48

Когда Вы используете LANG=C gcc ... то, что происходит, - то, что оболочка устанавливает ЛЕНГА для gccсреда только, а не для самой текущей среды (см. примечание). Таким образом после gccконцы, LANG вернулся к его предыдущему значению (или сброс).

Кроме того, когда Вы используете A=10 echo $A это - оболочка, которая заменяет $A, не отзываются эхом, и эта замена (названный "расширением") происходит, прежде чем оператор оценен (включая присвоение), так для работы как ожидалось Aзначение должно быть уже установлено в текущей среде до того оператора.

Вот почему A=10 echo $A не работает как ожидалось: A=10 будет установлен для эха, но эхо внутренне игнорирует значение переменной среды A. И $A заменяется набором значений в текущей оболочке (который не является ни одним), и затем передал как аргумент эху.

Таким образом, Ваше предположение корректно: VAR=value command действительно работает, но это только релевантно если command внутренне использование VAR. В противном случае можно все еще передать value как аргумент command, но аргументы заменяются текущей оболочкой, таким образом, они должны быть установлены до использования: VAR=value; command "$VAR"

Если Вы знаете, как создать исполняемый сценарий, можно попробовать это как тест:

#!/bin/sh
echo "1st argument is $1"
echo "A is $A"

Сохраните его как testscript и попытка:

$ A=5; A=10 testscript "$A"; echo "$A"
1st argument is 5
A is 10
5

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

Вот некоторые хорошие ссылки:

.

(*) Примечание: технически оболочка действительно устанавливает в текущей среде также и здесь почему: Некоторые команды, как echo, read и test оболочка builtins, и как таковой, они не порождают дочерний процесс. Они работают в текущей среде. Но оболочка заботится для присвоения, только длится, пока команда не работает, таким образом, для всех практических целей эффект является тем же: присвоение только замечено той единственной командой.

37
ответ дан 29 May 2014 в 14:48

Один возможно очевидный способ, чтобы сделать, чего Вы, по-видимому, требуете, должен дать команду:

A=10 eval 'echo $A'

, Который в действительности задержит замену значения 10 в место $A к более позднему контексту (т.е., 'в' оценке, которая уже знает о присвоении). Обратите внимание, что одинарные кавычки важны. Такая конструкция чисто передает присвоение на Вашу желаемую команду (эхо в этом случае), не рискуя загрязнять Вашу текущую среду.

0
ответ дан 29 May 2014 в 14:48

Другие вопросы по тегам:

Похожие вопросы: