Übergeben und Setzen von Variablen in einem Heredoc

17

Ich habe ein Skript, das viele verschiedene Dinge auf vielen verschiedenen Remote-Rechnern erledigen muss. Ich dachte, dass ein Heredoc dafür funktionieren würde, aber ich bin nicht in der Lage, eine Variable zu verwenden, die an anderer Stelle im Skript definiert ist, und eine, die im Heredoc definiert ist.

Hier ist ein Code:

#!/bin/sh

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

Dies druckt nur die folgenden:

FOO =

BAR = bar

Wenn ich die EOF-Zeile jedoch so zitiere: ssh some.remote.host << "EOF" dann gibt sie nur Folgendes aus:

FOO = foo

BAR =

Irgendwelche Hinweise, wie ich beide Variablen innerhalb des Heredocs verwenden kann?

Vielen Dank.

trubliphone
quelle

Antworten:

25

Kurz gesagt, verwenden Sie:

  • nicht zitierte heredoc-Schlüsselwörter, zB EOF
  • reguläres Dollarzeichen für äußere (dh lokale ) Variablen, zB$FOO
  • entkam Dollar Zeichen für innere (dh Fern ) Variablen, zB\$BAR

Wenn Sie das Heredoc-Schlüsselwort (dh EOF) nicht in Anführungszeichen setzen, wird der Heredoc-Text lokal verarbeitet, sodass er auf die leere Zeichenfolge $FOOerweitert foound auf diese BARerweitert wird. Dann wird Ihr sshBefehl:

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

Wenn Sie das Schlüsselwort heredoc in Anführungszeichen setzen, wird die Variablenerweiterung unterdrückt, sodass Ihr sshBefehl stattdessen wie folgt lautet :

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

Da dies FOOin der Remote-Shell-Umgebung wahrscheinlich nicht definiert ist, wird der Ausdruck "FOO=$FOO"als ausgewertet "FOO=''", dh FOOauf den leeren String gesetzt.

Wenn Sie beide Variablen verwenden möchten, müssen Sie das heredoc-Schlüsselwort nicht in Anführungszeichen setzen, damit die Variablenerweiterung für die lokal definierte Variable stattfindet, und dann die Variable, die Sie remote erweitern möchten (mit einem Backslash) :

#!/bin/sh

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

In diesem Fall lautet Ihr ssh-Befehl (wie vom Remote-Server empfangen) wie folgt:

  BAR="bar"
  echo "FOO=foo"
  echo "BAR=$BAR"
igal
quelle
1
Das ist genial! Ich habe ewig versucht, das herauszufinden. Vielen Dank für diese Lösung.
Trubliphone