Per zanco Antwort , ich sofern Sie nicht einen Remote - Befehl zu ssh, da , wie die Shell die Befehlszeile analysiert. Um dieses Problem zu lösen, ändern Sie die Syntax Ihres sshBefehlsaufrufs so, dass der Remote-Befehl aus einer syntaktisch korrekten mehrzeiligen Zeichenfolge besteht.
Es gibt verschiedene Syntaxen, die verwendet werden können. Da Befehle beispielsweise in bashund shund wahrscheinlich auch in andere Shells weitergeleitet werden können, besteht die einfachste Lösung darin, den sshShell-Aufruf einfach mit Heredocs zu kombinieren :
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Beachten Sie, dass das Ausführen der obigen Schritte ohne /bin/bash die Warnung führt Pseudo-terminal will not be allocated because stdin is not a terminal. Beachten Sie auch, dass dies EOTvon einfachen Anführungszeichen umgeben ist, sodass bashder Heredoc als Nowdoc erkannt wird und die Interpolation lokaler Variablen deaktiviert wird , sodass der Befehlstext unverändert übergeben wird ssh.
Wenn Sie ein Fan von Pfeifen sind, können Sie die oben genannten Punkte wie folgt umschreiben:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Die gleiche Einschränkung /bin/bashgilt für die oben genannten.
Ein anderer gültiger Ansatz besteht darin, den mehrzeiligen Remote-Befehl als einzelne Zeichenfolge zu übergeben, wobei mehrere Ebenen bashvariabler Interpolation wie folgt verwendet werden:
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
Die obige Lösung behebt dieses Problem auf folgende Weise:
ssh user@serverwird von bash analysiert und als sshBefehl interpretiert , gefolgt von einem Argument user@server, das an den sshBefehl übergeben werden soll
"beginnt eine interpolierte Zeichenfolge, die nach Abschluss ein Argument enthält, das an den sshBefehl übergeben werden soll. In diesem Fall wird dies als Remotebefehl interpretiert ssh, als den ausgeführt werden solluser@server
$( Startet die Ausführung eines Befehls, wobei die Ausgabe von der umgebenden interpolierten Zeichenfolge erfasst wird
catist ein Befehl zum Ausgeben des Inhalts einer beliebigen Datei. Die Ausgabe von catwird an die erfasste interpolierte Zeichenfolge zurückgegeben
<<beginnt ein Bash Heredoc
'EOT'Gibt an, dass der Name des Heredocs EOT ist. Die einfachen Anführungszeichen 'um EOT geben an, dass der Heredoc als Nowdoc analysiert werden soll. Dies ist eine spezielle Form des Heredoc, bei der der Inhalt nicht durch Bash interpoliert, sondern im Literalformat weitergegeben wird
Alle Inhalte, die zwischen <<'EOT'und <newline>EOT<newline>jetzt an die nowdoc-Ausgabe angehängt werden
EOTBeendet den NowDOC, wodurch eine temporäre NowDOC-Datei erstellt und an den aufrufenden catBefehl zurückgegeben wird. catgibt den nowdoc aus und gibt die Ausgabe an die erfasste interpolierte Zeichenfolge zurück
) schließt den auszuführenden Befehl ab
"schließt die erfasste interpolierte Zeichenfolge ab. Der Inhalt der interpolierten Zeichenfolge wird sshals einzelnes Befehlszeilenargument zurückgegeben, das sshals Remote-Befehl zur Ausführung interpretiert wirduser@server
Wenn Sie die Verwendung externer Tools wie z. B. vermeiden catmöchten und zwei Anweisungen anstelle einer Anweisung verwenden readmöchten , verwenden Sie die integrierte Funktion mit einem Heredoc, um den SSH-Befehl zu generieren:
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…