Це зводиться до питання, як працює оцінка. Обидва приклади працюють однаково, проблема трапляється через те, як оболонка (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.