É possível enviar um HEREDOC sobre ssh para um host remoto de dentro de um script sendo executado localmente?

6

Eu essencialmente quero rodar um script na máquina A que irá conectar o SSH na máquina B, executar comandos em B e retornar a saída para a máquina A.

Por isso, estou criando um script csh para fazer isso, espero, se for possível.

Por exemplo, essa solução de esta resposta funciona na linha de comando:

ssh user@host << 'ENDSSH'
ls -l
ENDSSH

Posso verificar se está executando o ls no controle remoto e não localmente.

No entanto, eu quero ser capaz de fazer isso dentro dos backticks, dentro do meu script csh rodando localmente. Isso seria possível?

Eu sei que é possível usar o SSH e executar um script que esteja no controle remoto, mas esse não é o meu caso.

Eu também ouvi dizer que é possível enviar um segundo script armazenado localmente sobre o SSH (que eu também não descobri), mas eu gosto da idéia de ter todos os comandos dentro do script original, daí o HEREDOC.

Eu sei que é uma questão bastante particular, mas se houver uma maneira, seria muito legal saber como.

Coisas que não funcionam

1)

'ssh user@host<<'ENDSSH''
'echo "ls -l"'
'echo "ENDSSH"'

Isso dá o erro:

stty: standard input: Invalid argument. %código% stty: standard input: Invalid argument.

E, em seguida, ele executa Warning: Command not found localmente e, em seguida, tentou executar ls -l localmente e, obviamente, falha com o comando não encontrado.

2)

'ssh user@host<<'ENDSSH''
echo "ls -l"
echo "ENDSSH"

O mesmo problema acima, exceto que exibe somente ENDSSH e ls -l como texto. Faz sentido ... já que a porção HEREDOC falhou.

3) 3-5 não são exatamente o que eu perguntei, mas ainda tentam apenas fazer com que o caso básico funcione.

'ssh user@host ls-l' 

Isso retorna ENDSSH Sim, eu não tenho ideia de onde isso está vindo.

4)

'cat ./test.csh | ssh user@host'

Também retorna o mesmo que tentativa # 1

5)

'cat ./test.csh | ssh -t user@host'

O mesmo que o número 1 e 4.

Estou começando a esgotar outras soluções do stackoverflow / Ubuntu / serverfault ... etc. A maioria das pessoas pergunta sobre como executar seu script em um controle remoto a partir da linha de comando, não como executar comandos em um controle remoto a partir de um script em execução localmente.

Editar

Bem, eu acho que tenho parte do problema resolvido. Com o caso 3 acima, por exemplo, o que acontece é que total: Command not found. é executado localmente e a primeira parte da saída é enviada por SSH como um comando.

Percebi isso porque tentei ls -l , com ssh user@host $CMD definido como $CMD . A saída foi "whoami" e, em seguida, percebi que username: Command not found é da saída ls. Ainda não tenho certeza sobre como resolver isso, embora

    
por krb686 03.03.2015 / 19:32

2 respostas

3

Se você envolver todo o comando que deseja executar dentro dos backticks, é provável que você obtenha a solução correta. Existem questões relativas à avaliação de variáveis e outros elementos interpolados, mas vou colocá-los de lado por um momento.

No entanto, não sei bem por que você quer algo nos backticks. Sua pergunta diz que você deseja executar um script local remotamente. Seu primeiro exemplo faz isso.

ssh -q user@host << ENDSSH
hostname
ls -l
id
ENDSSH

Talvez você queira obter a saída da execução remota em uma variável? Não diz isso em lugar algum na pergunta, mas você faria assim ( bash )

RESULT=$(ssh user@host <<ENDSSH
hostname
id
ENDSSH
)
...
echo "$RESULT"

Ou, desde que você mencionou csh , como este

set result = 'ssh -q user@host' <<ENDSSH
hostname
id
ENDSSH
...
echo "$result"

Observe que, para a variante csh , todas as linhas de saída são concatenadas juntas.

Vejo que você relatou um erro, stty: standard input: Invalid argument. Isso provavelmente está ocorrendo porque você tem um comando stty em seu script de login no servidor remoto. Isso deve ser envolvido em um teste para um shell interativo. Em bash você faria algo assim:

if test -n "$PS1"
then
    # Interactive setup here
    stty ...
fi
    
por 03.03.2015 / 20:45
1

Não sei o que você está tentando fazer, mas aqui está algo que funcionou para mim.

(O drat tem problemas em manter o editor de texto stackexchange de tratar os carrapatos anteriores como formatar caracteres, usando os forward para carrapatos anteriores).

R='ssh -t hostname <<EOF
ls -l
EOF'

Note que eu não fecho o backtick até depois do EOF e uso a opção -t para criar um TTY virtual mesmo que o stdio esteja sendo redirecionado.

    
por 03.03.2015 / 20:48