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 echo
ya cat
no 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 $X
expande antes de que se ejecute todo el comando, es decir, si $X
inicialmente 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 <<EOF
es 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 CHANGES
archivo 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 bash
realizará 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 bash
debe compilarse y pasarse al cat
momento de la invocación de la misma manera que debe asignarse 123
antes $X
de pasarlo más el resto de su entorno en ese cat
momento 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.