A correção do shellshock bash quebrou ferramentas básicas de linha de comando como echo e cat?

A correção do shellshock bash quebrou ferramentas básicas de linha de comando como echo e cat?

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 echoou catnã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 $Xnã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 CHANGESarquivo 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 bashexecutará 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 bashdeve ser construído e transmitido catna invocação, da mesma forma que deve ser atribuído 123antes $Xde passar isso e o restante de seu ambiente para catno execvemomento.

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.

informação relacionada