Почему этот код не работает?
Вопрос
x="a=b"
`echo $x`
echo $a
Я ожидаю, что вторая строка сгенерирует «a = b» и выполнит ее в контексте основной оболочки, что приведет к новой переменной a
с стоимостью b
Анкет Однако то, что я действительно получаю (если я введу команды вручную), это сообщение об ошибке после второй строки, bash: a=b: command not found
Почему это так?
Решение
Это из -за порядка, в котором Баш анализирует командную строку. Он ищет определения переменных (например, a=b
) до Выполнение переменной и замены команды (например, команды в образе). Из -за этого, к тому времени echo $x
заменяется a=b
, Слишком поздно, чтобы Bash рассматривал это как определение переменной, и вместо этого она проанализирована как команда. То же самое произошло, если бы вы только что использовали $x
как команда (вместо эхо в образе). Как в ответе @mvds, eval
Команда может использоваться, чтобы заставить команду быть восстановленной с самого начала, что означает, что она будет распознана как определение переменной:
$ x="a=b"
$ `echo $x`
-bash: a=b: command not found
$ $(echo $x) # Exact same thing, but with cleaner syntax
-bash: a=b: command not found
$ $x # This also does the same thing, but without some extra steps
-bash: a=b: command not found
$ eval "$x" # This will actually work
$ echo $a
b
$ a= # Start over
$ eval "$(echo "$x")" # Another way of doing the same thing, with extra steps
$ echo $a
b
Обратите внимание, что при использовании eval
Я положил все ссылки на $x
В двойных цитатах-это предотвращение более поздних этапов анализа Bash (например, разделение слов) дважды, поскольку Bash завершит свой регулярный процесс анализа, а затем распознает eval
командование, а затем переделать весь процесс анализа опять таки. Анкет Действительно легко получить неожиданные результаты от использования eval
, и это устраняет, по крайней мере, некоторые потенциал для неприятностей.
Другие советы
Пытаться
eval $x
(И нам нужно 30 символов для этого ответа)
То, что делает ваша первая линия Echo, работает в подборке и возвращает свое значение Callee. Тот же результат достигается с помощью с помощью $()
и, кстати, проще в использовании, чем бэктики.
Итак, то, что вы делаете, сначала бежит echo $x
(что возвращается a=b
) И, из -за обработков, a=b
возвращается в оболочку, которая пытается запустить эту строку как команду, которая, очевидно, не сработает.
Попробуйте это в оболочке:
$(echo ls)
И вы ясно увидите, что происходит.
Ты пробовал $x
В этих забавных апострофах? Без echo
, Echo, кажется, только для отображения строки, а не выполнять команды.