Eu costumava fazer coisas como:
X=123 cat <<EOF
X is $X
EOF
ou ainda mais simples:
X=123 echo $X
O primeiro ainda parece funcionar no Mac OS X depois de instalar a correção do bash, mas nenhum deles parece funcionar mais na minha instância do Ubuntu 14.04 na AWS. O que faz com que você tenha echo
ou cat
não mais acesso a essas variáveis de ambiente? Mais estranho ainda, quando passo os env vars para um aplicativo NodeJS, não pareço ter nenhum problema:
cat <<EOF > test.js
console.log('X is ' + process.env.X);
EOF
X=123 node test.js
Isso parece funcionar também em scripts bash:
cat <<EOF > test.sh
echo X is \$X
EOF
chmod +x test.sh
X=123 ./test.sh
Responder1
Em qualquer shell POSIX, quando você escreve
X=123 echo $X
o $X
é expandido antes de todo o comando ser executado, ou seja, se $X
não for definido inicialmente, você obterá:
X=123 echo
que é então executado. Você pode ver mais ou menos o que o shell está fazendo set -x
:
$ set -x
$ X=123 echo X=$X
+ X=123
+ echo X=
X=
$ set +x
Você pode ver que echo
(na verdade o próprio shell, que faz a expansão antes de executar echo
) ainda tem acesso ao ambiente:
$ X=123 eval 'echo $X'
123
O problema cat <<EOF
é semelhante. Observe que, com relação ao bash
, havia um bug nas versões antigas (antes da 4.1), descrito no CHANGES
arquivo como:
Corrigido um bug que fazia com que a expansão de variáveis nos documentos aqui aparecesse em qualquer ambiente temporário.
Esta pode ser a causa do comportamento observado no Mac OS X. Não confie neste bug.
Responder2
Suas perguntas sobre os documentos aqui provavelmente não estão relacionadas. O problema é que bash
executará as expansões e a atribuição simultaneamente - portanto, uma liderança X=123...
não deve afetar o valor expandido no documento aqui. Isso ocorre porque o aqui-documento é um descritor de arquivo de entrada que bash
deve ser construído e transmitido cat
na invocação, da mesma forma que deve ser atribuído 123
antes $X
de passar isso e o restante de seu ambiente para cat
no execve
momento.
Considerar:
X=321; X=123 bash <<HEREDOC
echo "$X is not yet \$X and $$ is not yet \$$."
HEREDOC
SAÍDA
321 is not yet 123 and 17134 is not yet 17225.