Я подозреваю, что это часть последовательности, которая ловит вас:
Слова, которые не являются переменными назначениями или перенаправлениями, раскрываются (см. Расширения оболочки). Если после раскрытия остаются какие-либо слова, первое слово считается именем команды, а остальные слова - аргументами.
Это из справочного руководства по Bash в разделе «Простое расширение команд».
В этом cmd=bash
примере переменные окружения не установлены, и bash обрабатывает командную строку через расширение параметра, оставляя bash -c "echo hi"
.
В этом prefix=hello=hi
примере снова нет присвоений переменных на первом проходе, поэтому обработка продолжается до раскрытия параметра, в результате чего появляется первое слово hello=hi
.
Как только назначения переменных были обработаны, они не обрабатываются повторно во время выполнения команды.
Смотрите обработку и ее результаты в разделе set -x
:
$ prefix=hello=hi
+ prefix=hello=hi
$ $prefix bash -c 'echo $hello'
+ hello=hi bash -c 'echo $hello'
-bash: hello=hi: command not found
$ hello=42 bash -c 'echo $hello'
+ hello=42
+ bash -c 'echo $hello'
42
Для более безопасной вариации «переменное расширение», как «переменные окружения» eval
, рассмотрим предложение wjandreaenv
:
prefix=hello=hi
env "$prefix" bash -c 'echo "$hello"'
hi
Это не строго присваивание переменной командной строки, так как мы используем env
основную функцию утилиты для присвоения переменных среды команде, но она выполняет ту же цель. $prefix
Переменный расширяются во время обработки командной строки, обеспечивая имя = значение env
, который передает его вместе с bash
.
env
Вместо этого вы можете использоватьeval
, который IIRC является более безопасным, но медленнее.