Сломало ли исправление shellshock bash основные инструменты командной строки, такие как echo и cat?

Сломало ли исправление shellshock bash основные инструменты командной строки, такие как echo и cat?

Раньше я мог делать такие вещи:

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

или еще проще:

X=123 echo $X

Первый, похоже, все еще работает на Mac OS X после установки исправления bash, однако ни один из них больше не работает на моем экземпляре Ubuntu 14.04 в AWS. Что делает его таким 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, когда вы пишете

X=123 echo $X

раскрывается $Xдо выполнения всей команды, т.е. если $Xизначально не установлен, то получится:

X=123 echo

который затем выполняется. Вы можете увидеть более или менее то, что делает оболочка с помощью set -x:

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

Вы можете видеть, что echo(фактически сама оболочка, которая выполняет расширение перед выполнением echo) по-прежнему имеет доступ к среде:

$ X=123 eval 'echo $X'
123

Проблема с cat <<EOFпохожа. Обратите внимание bash, что в старых версиях (до 4.1) была ошибка, описанная в CHANGESфайле как:

Исправлена ​​ошибка, из-за которой расширение переменных в документах выполнялось в любой временной среде.

Это может быть причиной поведения, наблюдаемого в Mac OS X. Не полагайтесь на эту ошибку.

решение2

Ваши вопросы относительно here-documents, вероятно, не связаны. Дело в том, что bashбудет выполнять расширения и присваивание одновременно - поэтому лидирующий элемент X=123...не должен влиять на значение, развернутое из here-document. Это потому, что here-document - это входной файловый дескриптор, который bashдолжен быть построен и передан catпри вызове таким же образом, как он должен назначить 123перед $Xпередачей этого и остальной части его окружения в catмомент execveвремени.

Учитывать:

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.

Связанный контент