Установка переменной среды для одного вызова программы в bash с использованием env

Я пытаюсь вызвать команду оболочки с измененной средой с помощью команды env.

Согласно руководству

env HELLO='Hello World' echo $HELLO

должен отражать Hello World, но это не так. Если я делаю

HELLO='Hello World' bash -c 'echo $HELLO'

он печатает Hello World, как и ожидалось (спасибо этот ответ за эту информацию).

Что мне здесь не хватает?

Cheers, Никлас

Ответ 1

Это потому, что в вашем первом случае ваша текущая оболочка расширяет переменную $HELLO перед запуском команд. И в вашей текущей оболочке нет переменной HELLO.

env HELLO='Hello World' echo $HELLO

сделает это:

  • развернуть любые заданные переменные, в этом случае $HELLO
  • запустите env с 3 аргументами HELLO = Hello World ',' echo 'и' '(пустая строка, так как в текущей оболочке нет переменной HELLO)
  • Команда env запустится и установит HELLO = 'Hello World' в своей среде
  • env будет запускать эхо с аргументом '' (пустая строка)

Как вы видите, текущая оболочка расширила переменную $HELLO, которая не установлена.

HELLO='Hello World' bash -c 'echo $HELLO'

сделает это:

  • установите переменную HELLO='Hello World для следующей команды
  • запустите bash с двумя аргументами "-c" и "echo $HELLO"
  • поскольку последний аргумент заключен в одинарные кавычки, все внутри него не расширяется
  • новый bash, в свою очередь, запустит команду echo $HELLO
  • Чтобы запустить echo $HELLO в новой под-оболочке bash, bash сначала расширяет все, что может, $HELLO в этом случае, а родительская оболочка устанавливает для нас "Hello World".
  • Подглавная оболочка запускает echo 'Hello World'

Если вы попытались сделать это, например, это:

env HELLO='Hello World' echo '$HELLO'

  • Текущая оболочка будет расширять все, что угодно, что ничего не значит, поскольку $HELLO заключен в одинарные кавычки
  • запустите env с тремя аргументами "HELLO = Hello World", "echo" и "$ HELLO"
  • Команда env запустится и установит HELLO = 'Hello World' в своей среде
  • env будет запускать эхо с аргументом $HELLO

В этом случае нет оболочки, которая будет расширять $HELLO, поэтому echo получает строку $HELLO и выводит ее. Расширение переменной выполняется только оболочками.

Ответ 2

Я думаю, что то, что происходит, похоже на эту ситуацию, в котором я также был озадачен.

В двух словах расширение переменной в первом случае выполняется текущей оболочкой, которая не имеет $HELLO в своей среде. Во втором случае одиночные кавычки не позволяют текущей оболочке выполнять расширение переменной, поэтому все работает так, как ожидалось.

Обратите внимание, что изменение одиночных кавычек в двойные кавычки не позволяет этой команде работать так, как вы хотите:

HELLO='Hello World' bash -c "echo $HELLO"

Теперь это приведет к сбою по той же причине, что и первая команда в вашем вопросе.

Ответ 3

Это работает и хорошо для меня

$ MY_VAR='Hello' ANOTHER_VAR='World!!!' && echo "$MY_VAR $ANOTHER_VAR"
Hello World!!!

Ответ 4

Вот простой способ подтвердить, что оболочка работает как ожидалось.

env A=42 env
env

Первая команда запускает набор A до 42 и запускает env. Вторая команда также запускает пробеги env. Сравните выходные данные обоих.