shellshock bash 修复是否破坏了 echo 和 cat 等基本命令行工具?

shellshock bash 修复是否破坏了 echo 和 cat 等基本命令行工具?

我曾经能够做这样的事情:

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

甚至更简单:

X=123 echo $X

安装 bash 修复后,第一个似乎仍然可以在 Mac OS X 上运行,但是似乎都不再可以在 AWS 中的 Ubuntu 14.04 实例上运行。是什么使得它echo不再cat能够访问这些环境变量?更奇怪的是,当我将环境变量传递给 NodeJS 应用程序时,我似乎没有任何问题:

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

这似乎也适用于 bash 脚本:

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

答案1

在任何 POSIX shell 中,当您编写

X=123 echo $X

the$X在执行整个命令之前展开,即如果$X最初未设置,您将得到:

X=123 echo

然后执行。您可以或多或少地看到 shell 正在做什么set -x

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

您可以看到echo(实际上是 shell 本身,它在执行之前进行扩展echo)仍然可以访问环境:

$ X=123 eval 'echo $X'
123

的问题cat <<EOF是类似的。请注意,关于bash,旧版本(4.1之前)存在一个错误,在CHANGES文件中描述为:

修复了导致此处文档中的变量扩展以在任何临时环境中查找的错误。

这可能是在 Mac OS X 下观察到的行为的原因。不要依赖此错误。

答案2

您对此处文档的问题可能与此无关。问题是,bash将同时执行扩展和赋值 - 因此前导X=123...不应影响从此处文档中扩展的值。这是因为此处文档是一个输入文件描述符,bash必须在调用时构建并传递给它,cat其方式与在传递该描述符及其环境的其余部分之前必须分配123的方式相同。$Xcatexecve

考虑:

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

输出

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

相关内容