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 ssh
Befehlsaufrufs 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 bash
und sh
und wahrscheinlich auch in andere Shells weitergeleitet werden können, besteht die einfachste Lösung darin, den ssh
Shell-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 EOT
von einfachen Anführungszeichen umgeben ist, sodass bash
der 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/bash
gilt für die oben genannten.
Ein anderer gültiger Ansatz besteht darin, den mehrzeiligen Remote-Befehl als einzelne Zeichenfolge zu übergeben, wobei mehrere Ebenen bash
variabler 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@server
wird von bash analysiert und als ssh
Befehl interpretiert , gefolgt von einem Argument user@server
, das an den ssh
Befehl übergeben werden soll
"
beginnt eine interpolierte Zeichenfolge, die nach Abschluss ein Argument enthält, das an den ssh
Befehl ü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
cat
ist ein Befehl zum Ausgeben des Inhalts einer beliebigen Datei. Die Ausgabe von cat
wird 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
EOT
Beendet den NowDOC, wodurch eine temporäre NowDOC-Datei erstellt und an den aufrufenden cat
Befehl zurückgegeben wird. cat
gibt 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 ssh
als einzelnes Befehlszeilenargument zurückgegeben, das ssh
als Remote-Befehl zur Ausführung interpretiert wirduser@server
Wenn Sie die Verwendung externer Tools wie z. B. vermeiden cat
möchten und zwei Anweisungen anstelle einer Anweisung verwenden read
mö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…