передача и установка переменных в heredoc


18

У меня есть скрипт, который должен делать много разных вещей на разных удаленных машинах. Я думал, что для этого подойдет heredoc, но я не могу использовать переменную, определенную в другом месте в сценарии, и переменную, определенную в heredoc.

Вот некоторый код:

#!/bin/sh

FOO="foo"
ssh some.remote.host << EOF
  BAR="bar"
  echo "FOO=$FOO"
  echo "BAR=$BAR"
EOF

Это только печатает следующее:

FOO =

BAR = бар

Однако, если я процитирую строку EOF следующим образом: ssh some.remote.host << "EOF" тогда она печатает только следующее:

FOO = Foo

BAR =

Любые советы о том, как я могу использовать обе переменные внутри heredoc?

Благодарю.

Ответы:


27

Короче говоря, используйте:

  • ключевые слова heredoc без кавычек, например, EOF
  • обычный символ доллара для внешних (то есть локальных ) переменных, например,$FOO
  • экранированный символ доллара для внутренних (т.е. удаленных ) переменных, например\$BAR

Если оставить Heredoc ключевого слова (то есть EOF) некотируемое то тело Heredoc обрабатывается локально, так что $FOOрасширяются до fooи BARрасширяются в пустую строку. Тогда ваша sshкоманда становится:

BAR="bar"
echo "FOO=foo"
echo "BAR="

Если вы заключите в кавычки ключевое слово heredoc, расширение переменной будет подавлено, так что ваша sshкоманда станет такой:

BAR="bar"
echo "FOO=$FOO"
echo "BAR=$BAR"

Поскольку FOO, вероятно, не определено в среде удаленной оболочки, выражение "FOO=$FOO"оценивается как "FOO=''", т.е. FOOустанавливается в пустую строку.

Если вы хотите использовать обе переменные, вам нужно оставить ключевое слово heredoc без кавычек, чтобы расширение переменной происходило для локальной переменной, а затем экранировать (с обратной косой чертой) переменную, которую вы хотите развернуть удаленно, т.е. :

#!/bin/sh

FOO="foo"
ssh some.remote.host << EOF
  BAR="bar"
  echo "FOO=$FOO"
  echo "BAR=\$BAR"
EOF

В этом случае ваша команда ssh (полученная удаленным сервером) будет следующей:

  BAR="bar"
  echo "FOO=foo"
  echo "BAR=$BAR"

1
Это замечательно! Я потратил целую вечность, пытаясь понять это. Большое спасибо за это решение.
трублифон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.