Ответ 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
и выводит ее. Расширение переменной выполняется только оболочками.