¿La solución de Shellshock Bash rompió las herramientas básicas de la línea de comandos como echo y cat?

¿La solución de Shellshock Bash rompió las herramientas básicas de la línea de comandos como echo y cat?

Solía ​​​​poder hacer cosas como:

X=123 cat <<EOF
X is $X
EOF

o incluso más simple:

X=123 echo $X

El primero todavía parece funcionar en Mac OS X después de instalar la solución bash, sin embargo, ninguno parece funcionar más en mi instancia de Ubuntu 14.04 en AWS. ¿Qué hace que echoya catno tengas acceso a estas variables de entorno? Más extraño aún, cuando paso las variables de entorno a una aplicación NodeJS, parece que no tengo ningún problema:

cat <<EOF > test.js
console.log('X is ' + process.env.X);
EOF
X=123 node test.js

Esto también parece funcionar en scripts bash:

cat <<EOF > test.sh
echo X is \$X
EOF
chmod +x test.sh
X=123 ./test.sh

Respuesta1

En cualquier shell POSIX, cuando escribes

X=123 echo $X

se $Xexpande antes de que se ejecute todo el comando, es decir, si $Xinicialmente no está configurado, se obtiene:

X=123 echo

que luego se ejecuta. Puedes ver más o menos lo que está haciendo el shell con set -x:

$ set -x
$ X=123 echo X=$X
+ X=123
+ echo X=
X=
$ set +x

Puedes ver que echo(en realidad, el propio shell, que realiza la expansión antes de ejecutarse echo) todavía tiene acceso al entorno:

$ X=123 eval 'echo $X'
123

El problema cat <<EOFes similar. Tenga en cuenta que, con respecto a bash, hubo un error en las versiones anteriores (anteriores a la 4.1), que se describe en el CHANGESarchivo como:

Se corrigió un error que causaba que la expansión variable en estos documentos se viera en cualquier entorno temporal.

Esta puede ser la causa del comportamiento observado en Mac OS X. No confíe en este error.

Respuesta2

Sus preguntas sobre los documentos aquí probablemente no estén relacionadas. La cuestión es que bashrealizará las expansiones y la asignación al mismo tiempo, por lo que un interlineado X=123...no debería afectar el valor expandido desde el documento aquí. Esto se debe a que el documento aquí es un descriptor de archivo de entrada que bashdebe compilarse y pasarse al catmomento de la invocación de la misma manera que debe asignarse 123antes $Xde pasarlo más el resto de su entorno en ese catmomento execve.

Considerar:

X=321; X=123 bash <<HEREDOC
echo "$X is not yet \$X and $$ is not yet \$$."
HEREDOC

PRODUCCIÓN

321 is not yet 123 and 17134 is not yet 17225.

información relacionada