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.

相關內容