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 ssh
invocació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 bash
y sh
, y probablemente también en otros shells, la solución más simple es combinar la ssh
invocació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 EOT
está rodeado de comillas simples, por lo que bash
reconoce 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/bash
aplica 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 bash
interpolació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@server
bash lo analiza y se interpreta como el ssh
comando, seguido de un argumento user@server
que se debe pasar al ssh
comando
"
comienza una cadena interpolada, que cuando se complete, comprenderá un argumento que se pasará al ssh
comando, que en este caso se interpretará ssh
como el comando remoto para ejecutar comouser@server
$(
comienza un comando que se ejecutará, con la salida capturada por la cadena interpolada circundante
cat
es un comando para generar el contenido del archivo que sigue. La salida de cat
se 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
EOT
termina el nowdoc, lo que da como resultado que se cree un archivo temporal de nowdoc y se lo devuelva al cat
comando de llamada . cat
genera 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á ssh
como un argumento de línea de comando único, que ssh
se 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 read
incorporado 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…