Per Antwort von zanco geben Sie keinen Fernbefehl an ssh
wie die Shell die Befehlszeile analysiert. Um dieses Problem zu lösen, ändern Sie die Syntax Ihrer ssh
Befehlsaufruf, so dass der Fernbefehl aus einer syntaktisch korrekten, mehrzeiligen Zeichenfolge besteht.
Es gibt eine Vielzahl von Syntaxen, die verwendet werden können. Da Befehle zum Beispiel in bash
y sh
und wahrscheinlich auch andere Muscheln, ist die einfachste Lösung, einfach zu kombinieren ssh
Shell-Aufruf mit Heredocs:
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 die Ausführung der oben genannten ohne /bin/bash
führt zu der Warnung Pseudo-terminal will not be allocated because stdin is not a terminal
. Beachten Sie auch, dass EOT
ist von einfachen Anführungszeichen umgeben, so dass bash
erkennt den Heredoc als einen nowdoc und schaltet die Interpolation lokaler Variablen aus, so dass der Befehlstext unverändert an ssh
.
Wenn Sie ein Fan von Pfeifen sind, können Sie den obigen Text 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
Derselbe Vorbehalt gilt für /bin/bash
gilt für die oben genannten Punkte.
Ein anderer gültiger Ansatz ist die Übergabe des mehrzeiligen Remote-Befehls als eine einzige Zeichenkette unter Verwendung mehrerer Schichten von bash
variable Interpolation wie folgt:
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@server
wird von der Bash geparst und so interpretiert, dass es die ssh
Befehl, gefolgt von einem Argument user@server
die an den ssh
Befehl
-
"
beginnt eine interpolierte Zeichenkette, die, wenn sie fertig ist, ein Argument darstellt, das an den ssh
Befehl, der in diesem Fall interpretiert wird von ssh
als den auszuführenden Fernbefehl als user@server
-
$(
beginnt einen auszuführenden Befehl, wobei die Ausgabe durch die umgebende interpolierte Zeichenkette erfasst wird
-
cat
ist ein Befehl zur Ausgabe des Inhalts der folgenden Datei. Die Ausgabe von cat
wird in die erfassende interpolierte Zeichenkette zurückgegeben
-
<<
beginnt einen Bash heredoc
-
'EOT'
gibt an, dass der Name der Heredoc EOT ist. Die einfachen Anführungszeichen '
umgebende EOT gibt an, dass das Heredoc als nowdoc , eine spezielle Form von heredoc, bei der der Inhalt nicht von der Bash interpoliert wird, sondern als Literal weitergegeben wird
-
Jeder Inhalt, der zwischen <<'EOT'
y <newline>EOT<newline>
wird an die nowdoc-Ausgabe angehängt
-
EOT
beendet nowdoc, was dazu führt, dass eine temporäre nowdoc-Datei erstellt und an den Aufrufer zurückgegeben wird cat
Befehl. cat
gibt den nowdoc aus und übergibt die Ausgabe zurück an den einfangenden interpolierten String
-
)
schließt den auszuführenden Befehl ab
-
"
schließt die erfasste interpolierte Zeichenfolge ab. Der Inhalt der interpolierten Zeichenkette wird zurückgegeben an ssh
als einzelnes Kommandozeilenargument, das ssh
wird als der auszuführende Fernbefehl interpretiert als user@server
Wenn Sie die Verwendung externer Tools wie cat
zu verwenden, und wenn es Ihnen nichts ausmacht, zwei Anweisungen anstelle einer zu haben, verwenden Sie die read
mit einem heredoc eingebaut, um den SSH-Befehl zu erzeugen:
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}"