Según la respuesta de zanco , no está proporcionando un comando remoto ssh, dada la forma en que el shell analiza la línea de comando. Para resolver este problema, cambie la sintaxis de la sshinvocación de su comando para que el comando remoto esté compuesto por una cadena de varias líneas sintácticamente correcta.
Hay una variedad de sintaxis que se pueden usar. Por ejemplo, dado que los comandos se pueden canalizar bashy sh, y probablemente también en otros shells, la solución más simple es combinar la sshinvocación de shell con heredocs:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Tenga en cuenta que ejecutar lo anterior sin /bin/bash generará la advertencia Pseudo-terminal will not be allocated because stdin is not a terminal. También tenga en cuenta que EOTestá rodeado de comillas simples, por lo que bashreconoce el heredoc como un nowdoc , desactivando la interpolación de variables locales para que el texto del comando se pase como está a ssh.
Si eres fanático de las tuberías, puedes reescribir lo anterior de la siguiente manera:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
La misma advertencia se /bin/bashaplica a lo anterior.
Otro enfoque válido es pasar el comando remoto de varias líneas como una sola cadena, utilizando múltiples capas de bashinterpolación variable de la siguiente manera:
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
La solución anterior soluciona este problema de la siguiente manera:
ssh user@serverbash lo analiza y se interpreta como el sshcomando, seguido de un argumento user@serverque se debe pasar al sshcomando
"comienza una cadena interpolada, que cuando se complete, comprenderá un argumento que se pasará al sshcomando, que en este caso se interpretará sshcomo el comando remoto para ejecutar comouser@server
$( comienza un comando que se ejecutará, con la salida capturada por la cadena interpolada circundante
cates un comando para generar el contenido del archivo que sigue. La salida de catse devolverá a la cadena interpolada de captura
<<comienza un golpe heredoc
'EOT'especifica que el nombre del heredoc es EOT. Las comillas simples que 'rodean a EOT especifican que el heredoc debe analizarse como un nowdoc , que es una forma especial de heredoc en la que los contenidos no se interpolan por bash, sino que se transmiten en formato literal
Cualquier contenido que se encuentre entre <<'EOT'y <newline>EOT<newline>se agregará a la salida de nowdoc
EOTtermina el nowdoc, lo que da como resultado que se cree un archivo temporal de nowdoc y se lo devuelva al catcomando de llamada . catgenera el nowdoc y devuelve el resultado a la cadena interpolada de captura
) concluye el comando a ejecutar
"concluye la cadena de captura interpolada. El contenido de la cadena interpolada se devolverá sshcomo un argumento de línea de comando único, que sshse interpretará como el comando remoto para ejecutar comouser@server
Si necesita evitar el uso de herramientas externas como cat, y no le importa tener dos declaraciones en lugar de una, use el readincorporado con un heredoc para generar el comando 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…