Это сводится к вопросу о том, как работает оценка. Оба примера работают одинаково, проблема возникает из-за того, что оболочка (здесь, bash) расширяет переменные.
Когда вы пишете эту команду:
HOME="foo" echo $HOME
$HOMEРасширяется до команды запуска . Следовательно, оно расширяется до исходного значения, а не до нового значения, установленного для команды. HOMEПеременная действительно были изменены в среде , что echoкоманда работает в, однако, вы печатаете $HOMEот родителя.
Для иллюстрации рассмотрим это:
$ HOME="foo" bash -c 'echo $HOME'
foo
$ echo $HOME
/home/terdon
Как вы можете видеть выше, первая команда печатает временно измененное значение, HOMEа вторая печатает оригинал, демонстрируя, что переменная была изменена только временно. Поскольку bash -c ...команда заключена в одинарные кавычки ( ' ') вместо двойных ( " "), переменная не раскрывается и передается как есть новому процессу bash. Этот новый процесс затем расширяет его и печатает новое значение, для которого он был установлен. Вы можете увидеть это, если вы используете set -x:
$ set -x
$ HOME="hello" echo "$HOME"
+ HOME=hello
+ echo hello
hello
Как вы можете видеть выше, переменная $HOME никогда не передается echo. Он видит только его расширенное значение. Сравнить с:
$ HOME="hello" bash -c 'echo $HOME'
+ HOME=hello
+ bash -c 'echo $HOME'
hello
Здесь из-за одинарных кавычек переменная, а не ее значение передаются новому процессу.
local.