De acordo com a resposta do zanco , você não está fornecendo um comando remoto ssh
, considerando como o shell analisa a linha de comando. Para resolver esse problema, altere a sintaxe da sua ssh
chamada de comando para que o comando remoto seja composto por uma cadeia de linhas multilinhas sintaticamente correta.
Há uma variedade de sintaxes que podem ser usadas. Por exemplo, como os comandos podem ser canalizados bash
e sh
, e provavelmente outros shells, a solução mais simples é combinar a ssh
chamada de shell com os heredocs:
ssh user@server /bin/bash <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
Observe que a execução acima sem /bin/bash
resultará no aviso Pseudo-terminal will not be allocated because stdin is not a terminal
. Observe também que EOT
está entre aspas simples, de modo que bash
reconhece o heredoc como um nowoc , desativando a interpolação de variável local para que o texto do comando seja passado como está ssh
.
Se você é um fã de pipes, pode reescrever o que foi dito acima, da seguinte maneira:
cat <<'EOT' | ssh user@server /bin/bash
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
A mesma ressalva /bin/bash
se aplica ao acima.
Outra abordagem válida é passar o comando remoto com várias linhas como uma única sequência, usando várias camadas de bash
interpolação de variáveis da seguinte maneira:
ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
echo "They are executed by: $( whoami )"
EOT
)"
A solução acima corrige esse problema da seguinte maneira:
ssh user@server
é analisado pelo bash e é interpretado como o ssh
comando, seguido por um argumento user@server
a ser passado ao ssh
comando
"
inicia uma cadeia de caracteres interpolada que, quando concluída, compreenderá um argumento a ser passado para o ssh
comando, que neste caso será interpretado ssh
como o comando remoto a ser executado comouser@server
$(
inicia um comando a ser executado, com a saída sendo capturada pela sequência interpolada circundante
cat
é um comando para gerar o conteúdo de qualquer arquivo a seguir. A saída de cat
será passada de volta para a sequência interpolada de captura
<<
começa um heredoc da festança
'EOT'
especifica que o nome do heredoc é EOT. As aspas simples ao '
redor do EOT especificam que o heredoc deve ser analisado como um nowdoc , que é uma forma especial de heredoc na qual o conteúdo não é interpolado pelo bash, mas transmitido no formato literal
Qualquer conteúdo encontrado entre <<'EOT'
e <newline>EOT<newline>
será anexado à saída nowdoc
EOT
finaliza o nowdoc, resultando em um arquivo temporário do nowdoc sendo criado e transmitido de volta ao cat
comando de chamada . cat
gera o nowdoc e passa a saída de volta para a sequência interpolada de captura
)
conclui o comando a ser executado
"
conclui a captura da cadeia interpolada. O conteúdo da cadeia de caracteres interpolada será passado de volta para ssh
um único argumento de linha de comando, que ssh
interpretará como o comando remoto para executar comouser@server
Se você precisar evitar o uso de ferramentas externas como cat
, e não se importar de ter duas instruções em vez de uma, use o read
built-in com um heredoc para gerar o 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…