Раньше я мог делать такие вещи:
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.