/bin/bash<<EOF
#!/bin/bash
echo $BASH_VERSION
EOF
Как вы можете заключить из сообщения об ошибке, heredo c расширяется до:
/bin/bash<<EOF
#!/bin/bash
echo 5.0.17(1)-release
EOF
Похоже, это то, что вы ожидаете: это расширен до версии внешней оболочки. Проблема не в heredo c или расширении; Дело в том, что круглые скобки без кавычек являются синтаксической ошибкой. Попробуйте запустить вручную команду echo
, и вы получите ту же ошибку:
$ echo 5.0.17(1)-release
bash: syntax error near unexpected token `('
Чтобы исправить это, вы можете добавить дополнительные кавычки:
/bin/bash<<EOF
echo '$BASH_VERSION'
EOF
Это будет работать и распечатайте версию внешней оболочки. Я использовал одинарные кавычки, чтобы продемонстрировать, что эти кавычки не будут препятствовать расширению переменных. Внешняя оболочка не видит этих кавычек. Только внутренняя оболочка.
(Я также избавился от строки #!/bin/bash
shebang. В этом нет необходимости, поскольку вы явно вызываете bash.)
Однако цитирование не является 100% надежным. Если $BASH_VERSION
содержит одинарные кавычки, у вас возникнут проблемы. Кавычки делают скобки (
)
безопасными, но они не надежны. В качестве общей техники, если вы хотите, чтобы это было полностью безопасно независимо от того, какие специальные символы находятся в игре , вам придется прыгать через некоторые уродливые обручи.
Используйте printf '%q'
, чтобы экранировать все специальные символы.
/bin/bash <<EOF
echo $(printf '%q' "$BASH_VERSION")
EOF
Это будет расширено до echo 5.0.17\(1\)-release
.
Передайте его как переменную среды и используйте <<'EOF'
чтобы отключить интерполяцию внутри скрипта.
OUTER_VERSION="$BASH_VERSION" /bin/bash <<'EOF'
echo "$OUTER_VERSION"
EOF
Это был бы мой выбор. По возможности я предпочитаю использовать форму <<'EOF'
. Если родительская оболочка интерполирует скрипт, передаваемый дочерней оболочке, это может сбивать с толку и вызывать затруднения. Кроме того, явная переменная $OUTER_VERSION
проясняет, что происходит.
Используйте bash -c 'script'
вместо heredo c, а затем передайте версию в качестве аргумента командной строки .
bash -c 'echo "$1"' bash "$BASH_VERSION"
Я мог бы go с этим для однострочного скрипта.