Selon la réponse de Zanco , vous ne fournissez pas de commande à distance ssh, étant donné la façon dont le shell analyse la ligne de commande. Pour résoudre ce problème, modifiez la syntaxe de votressh appel de commande afin que la commande distante soit composée d'une chaîne multi-lignes syntaxiquement correcte.
Il existe une variété de syntaxes qui peuvent être utilisées. Par exemple, puisque les commandes peuvent être canalisées dans bashet sh, et probablement aussi d'autres shells, la solution la plus simple est de simplement combiner l' sshinvocation du shell avec heredocs:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Notez que l'exécution de ce qui précède sans /bin/bash entraînera l'avertissement Pseudo-terminal will not be allocated because stdin is not a terminal. Notez également qu'il EOTest entouré de guillemets simples, ce qui bashreconnaît l'heredoc comme un nowdoc , désactivant l'interpolation de variable locale afin que le texte de la commande soit transmis tel quel àssh .
Si vous êtes un fan de tuyaux, vous pouvez réécrire ce qui suit comme suit:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
La même mise en garde à propos de /bin/bash s'applique à ce qui précède.
Une autre approche valide consiste à passer la commande à distance multi-ligne en une seule chaîne, en utilisant plusieurs couches d' bashinterpolation variable comme suit:
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
La solution ci-dessus résout ce problème de la manière suivante:
ssh user@serverest analysé par bash, et est interprété comme étant la sshcommande, suivi d'un argument user@serverà passer à la sshcommande
"commence une chaîne interpolée qui, une fois terminée, comprendra un argument à passer à la sshcommande, qui dans ce cas sera interprété par sshcomme étant la commande distante à exécuter commeuser@server
$( commence une commande à exécuter, la sortie étant capturée par la chaîne interpolée environnante
catest une commande pour afficher le contenu du fichier suivant. La sortie de catsera retransmise dans la chaîne interpolée de capture
<<commence un hérédoc bash
'EOT'spécifie que le nom de l'hérédoc est EOT. Les guillemets simples 'entourant EOT spécifient que l'heredoc doit être analysé en tant que nowdoc , qui est une forme spéciale d'heredoc dans laquelle le contenu n'est pas interpolé par bash, mais plutôt transmis au format littéral
Tout contenu rencontré entre <<'EOT'et <newline>EOT<newline>sera ajouté à la sortie nowdoc
EOTtermine nowdoc, ce qui entraîne la création et la retransmission d'un fichier temporaire nowdoc à la catcommande appelante . catsort le nowdoc et retransmet la sortie à la chaîne interpolée de capture
) conclut la commande à exécuter
"conclut la capture de la chaîne interpolée. Le contenu de la chaîne interpolée sera retransmis en sshtant qu'argument de ligne de commande unique, qui sshsera interprété comme la commande distante à exécuter commeuser@server
Si vous devez éviter d'utiliser des outils externes comme cat, et cela ne vous dérange pas d'avoir deux instructions au lieu d'une, utilisez le readintégré avec un hérédoc pour générer la commande SSH:
IFS='' read -r -d '' SSH_COMMAND <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
ssh user@server "${SSH_COMMAND}"
ssh user@server /bin/bash <<EOT…