passage et définition de variables dans un hérédoc

18

J'ai un script qui doit faire beaucoup de choses différentes sur de nombreuses machines distantes différentes. Je pensais qu'un hérédoc fonctionnerait pour cela, mais je ne suis pas en mesure d'utiliser une variable définie ailleurs dans le script et une définie dans l'hérédoc.

Voici du code:

#!/bin/sh

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

Cela n'imprime que les éléments suivants:

FOO =

BAR = bar

Si, cependant, je cite la ligne EOF comme ceci: ssh some.remote.host << "EOF" alors elle n'imprime que ce qui suit:

FOO = foo

BAR =

Des conseils sur la façon dont je peux utiliser les deux variables dans l'hérédoc?

Merci.

trubliphone
la source

Réponses:

27

En bref, utilisez:

  • des mots clés hérédoc non cités, par exemple, EOF
  • caractère en dollars réguliers pour les variables externes (c.-à-d. locales ), p. ex.$FOO
  • caractère dollar échappé pour les variables internes (c'est-à-dire distantes ), par exemple\$BAR

Si vous laissez le mot clé heredoc (c.-à-d. EOF) Sans guillemets, le corps heredoc est traité localement, de sorte qu'il $FOOest étendu à fooet BARest étendu à la chaîne vide. Votre sshcommande devient alors:

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

Si vous citez le mot clé heredoc, l'expansion des variables est supprimée, de sorte que votre sshcommande devienne celle-ci à la place:

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

Étant donné que FOOn'est probablement pas défini dans l'environnement shell distant, l'expression "FOO=$FOO"est évaluée comme "FOO=''", c'est FOO-à- dire est définie sur la chaîne vide.

Si vous souhaitez utiliser les deux variables, vous devrez laisser le mot-clé heredoc sans guillemets, afin que l'expansion de variable ait lieu pour la variable définie localement, puis échapper (avec une barre oblique inverse) la variable que vous souhaitez développer à distance, c'est-à-dire :

#!/bin/sh

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

Dans ce cas, votre commande ssh (telle que reçue par le serveur distant) sera la suivante:

  BAR="bar"
  echo "FOO=foo"
  echo "BAR=$BAR"
igal
la source
1
C'est génial! J'ai passé des siècles à essayer de comprendre cela. Merci beaucoup pour cette solution.
trubliphone