przekazywanie i ustawianie zmiennych w heredoc

18

Mam skrypt, który musi wykonywać wiele różnych czynności na wielu różnych zdalnych komputerach. Myślałem, że heredoc do tego zadziała, ale nie jestem w stanie użyć zmiennej zdefiniowanej gdzie indziej w skrypcie i zmiennej zdefiniowanej w heredoc.

Oto kod:

#!/bin/sh

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

Spowoduje to tylko wydrukowanie następujących elementów:

FOO =

BAR = bar

Jeśli jednak cytuję wiersz EOF w ten sposób: ssh some.remote.host << "EOF" wypisuje tylko następujące:

FOO = foo

BAR =

Wszelkie wskazówki na temat tego, jak mogę używać obu zmiennych w heredoc?

Dzięki.

trubliphone
źródło

Odpowiedzi:

27

W skrócie użyj:

  • niecytowane słowa kluczowe heredoc, np. EOF
  • zwykły znak dolara dla zmiennych zewnętrznych (tj. lokalnych ), np.$FOO
  • znak ucieczki dolara dla zmiennych wewnętrznych (tj. zdalnych ), np\$BAR

Jeśli pozostawisz słowo kluczowe heredoc (tj. EOF) Bez cudzysłowu, ciało heredoc jest przetwarzane lokalnie, więc $FOOjest rozwijane do fooi BARjest rozwijane do pustego ciągu. Wtedy twoje sshpolecenie staje się:

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

Jeśli zacytujesz słowo kluczowe heredoc, wówczas rozwinięcie zmiennej jest pomijane, dzięki czemu twoje sshpolecenie staje się takie:

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

Ponieważ FOOprawdopodobnie nie jest zdefiniowane w środowisku zdalnej powłoki, wyrażenie "FOO=$FOO"jest oceniane jako "FOO=''", tzn. FOOUstawione na pusty ciąg.

Jeśli chcesz użyć obu zmiennych, musisz pozostawić słowo kluczowe heredoc bez cudzysłowu, aby rozwinięcie zmiennej miało miejsce dla zmiennej zdefiniowanej lokalnie, a następnie uciec (odwrotnym ukośnikiem) zmienną, którą chcesz rozwinąć zdalnie, tj. :

#!/bin/sh

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

W takim przypadku polecenie ssh (otrzymane przez serwer zdalny) będzie następujące:

  BAR="bar"
  echo "FOO=foo"
  echo "BAR=$BAR"
igal
źródło
1
To jest niesamowite! Spędziłem wieki próbując to rozgryźć. Dziękuję bardzo za to rozwiązanie.
trubliphone