“Wrapper” script ssh congela ao executar o comando remoto

1

Estou executando o OSX Mountain Lion e o servidor remoto é o CentOS 6. Tenho vários scripts em minha máquina local que quero executar no servidor remoto e, para esse fim, pensei em escrever um script que se conecte via ssh leva um segundo script para executar como um parâmetro. Desta forma, eu posso escrever scripts bash naturalmente sem ter que me preocupar com o ssh e todas as preocupações que vêm com isso, e os mesmos scripts também poderiam ser reutilizados em minha máquina local. Por exemplo,

exec_remote.sh

!#/bin/bash
ssh -t -t jeff@remoteserver 'bash -s' < $1

make_dir.sh (observe o sudo)

!#/bin/bash
sudo mkdir -p /some/path/to/a/new/location

E a ideia é correr como

./exec_remote.sh make_dir.sh

Eu tive muitos problemas, a maioria dos quais eu consegui superar. No entanto, agora, quando executo os scripts como acima, o terminal trava por vários minutos, o diretório remoto não é criado e não há mensagem de erro.

Além disso, como eu não chamei logout , ainda tenho o terminal ssh aberto e todos os comandos subseqüentes (ou seja, ls ) estão completamente congelados. Eu deixei um ls rodar por 70 minutos antes de quebrá-lo. Nota: Eu não me importo em executar comandos depois; Eu simplesmente incluo isso como um sintoma do que está errado.

Como corrijo isso? Ou melhor ainda, existe uma maneira melhor de abordar esse problema?

EDITAR

Se eu atualizar meu script make_dir.sh para criar um diretório que não exija sudo , o script será executado normalmente de maneira normal, conforme o esperado. Existe um problema conhecido com a execução de comandos do sudo remotamente? Talvez apenas com o CentOS?

    
por Jeff 22.01.2013 / 18:11

4 respostas

3

Tente executar o script remotamente em segundo plano redirecionando std out e std err para um arquivo de log. Para que seu shell retorne (ou seja, "não fique bloqueado por muito tempo enquanto o script é executado"), você precisará usar o nohup e redirecionar todos os canais: StdOut, StdIn, StdErr. Por exemplo:

ssh jeff@remoteserver 'nohup make_dir.sh >> /tmp/log_file 2>&1 </dev/null &'

O comando acima fará o login no servidor remoto e executará make_dir.sh em segundo plano ao redirecionar StdOut e StdErr para / tmp / log_file. O StdIn é redirecionado de / dev / null. Caso contrário, o ssh será interrompido até que o script seja concluído.

Você mencionou que o roteiro leva um longo tempo para ser concluído. executar o script desta maneira deve permitir que você faça o login novamente e examine o que está acontecendo.

    
por 31.01.2013 / 20:01
3

Sua maneira de executar o ssh tem uma falha fundamental, que é: você só tem um stdin. Como você está lendo o script usando < , o stdin é "preenchido" com o conteúdo do script. E mesclado com sua entrada (neste caso, sua senha). O que não pode funcionar.

Portanto, a única maneira que vejo para isso funcionar é: você tem que copiar o script para o servidor remoto e, em seguida, iniciar um comando ssh que apenas executa esse script. Então, algo nesse sentido:

#!/bin/bash
USERHOST=jeff@remoteserver

ssh -o ControlMaster=yes -o ControlPersist=3600 -o ControlPath=/tmp/ssh-master-$USER-%r@%h:%p -Nf $USERHOST
trap "ssh -o ControlPath=/tmp/ssh-master-$USER-%r@%h:%p $USERHOST -O exit" exit

TEXEC=$(ssh $USERHOST mktemp)
scp $1 ${USERHOST}:${TEXEC}
ssh -t -t $USERHOST $TEXEC

Este script abre uma conexão compartilhável com o servidor remoto (então você só precisa digitar sua senha SSH uma vez), então copia seu script de shell e finalmente o executa usando o comando normal ssh , que permite alocar um TTY, e assim permite que sua senha seja inserida para sudo de uma maneira (relativamente) segura. No final do script wrapper, a conexão compartilhada é fechada por meio do exit trap.

    
por 30.01.2013 / 10:40
2

Apenas faça

ssh -t -t jeff@remoteserver $1

para executar o comando (verifique se é executável) e saia.

bash -s com deixe a sessão do bash aberta.

Você provavelmente deseja $ * em vez de $ 1 para poder transmitir argumentos ao script que está chamando

    
por 22.01.2013 / 18:26
0

Acho que entendo o que você quer. Execute o arquivo local na máquina remota.

cat seu arquivo local através de um pipe em bash remoto

por exemplo, para testar

$ echo "ls -l" | ssh jeff@remoteserver "bash " 

no script

cat $1 | ssh jeff@remoteserver "bash "
    
por 04.02.2013 / 15:51