Isso se resume a uma questão de como a avaliação funciona. Os dois exemplos funcionam da mesma maneira, o problema acontece porque o shell (bash, aqui) expande as variáveis.
Quando você escreve este comando:
HOME="foo" echo $HOME
O $HOME
é expandido antes do comando ser executado . Portanto, ele é expandido para o valor original e não para o novo que você definiu para o comando. A variável HOME
foi realmente alterada no ambiente em que o comando echo
está sendo executado, no entanto, você está imprimindo o $HOME
do pai.
Para ilustrar, considere isto:
$ HOME="foo" bash -c 'echo $HOME'
foo
$ echo $HOME
/home/terdon
Como você pode ver acima, o primeiro comando imprime o valor temporariamente alterado de HOME
e o segundo imprime o original, demonstrando que a variável foi alterada apenas temporariamente. Como o comando bash -c ...
está entre aspas simples ( ' '
) em vez das duplas ( " "
), a variável não é expandida e é passada como está para o novo processo bash. Esse novo processo, em seguida, expande e imprime o novo valor para o qual foi definido. Você pode ver isso acontecer se você usar set -x
:
$ set -x
$ HOME="hello" echo "$HOME"
+ HOME=hello
+ echo hello
hello
Como você pode ver acima, a variável $HOME
nunca é passada para echo
. Só vê seu valor expandido. Compare com:
$ HOME="hello" bash -c 'echo $HOME'
+ HOME=hello
+ bash -c 'echo $HOME'
hello
Aqui, por causa das aspas simples, a variável e não seu valor são passados para o novo processo.