Estou criando scripts de implantação para o meu projeto e criando uma função que deve ser capaz de executar um comando local e remotamente (em um servidor através do ssh) e retornar a saída de texto.
Ao executar um comando local, posso saber facilmente se o comando foi concluído aguardando seu PID. Quando envio um comando por uma conexão SSH aberta, recebo a saída novamente, mas não sei se o comando saiu ou se o comando ainda está em execução e gerará mais saída posteriormente.
Atualmente, eu "resolvi" isso abrindo uma nova conexão com o servidor para cada comando, o que nem é preciso dizer que é terrivelmente lento .
Parece que isso pode ser um problema comum e pode ter uma solução simples, talvez até algo embutido no SSH, por isso estou perguntando aqui: Como posso, em uma conexão SSH aberta, saber se os comandos que eu tenho enviado estão concluídos. Se eu pudesse, de alguma forma, coletar o código de saída também seria ótimo.
Para dar um exemplo mais concreto, isso basicamente demonstra meu problema no Ruby:
io = IO.popen(["ssh", "-q", "my-server"], "r+")
io.write("some command\n")
# Sleep for some arbitrary amount of time, because I don't know when the
# command has finished :(
sleep 1
output = io.readpartial(1_000_000)
io.write("some command\n")
# Sleep for some arbitrary amount of time, because I don't know when the
# command has finished :(
sleep 1
output = io.readpartial(1_000_000)
Mycommnad; InterestingPID=$? ; ... ;wait $InterestingPID
como comando de várias linhas da instrução ssh? BTW você pode usarwait
?my_command -myoptions AndParameters
) comLetsStoreInterestingPID=$?
apenas após o comando, e depois de alguns outros comandoswait $LetsStoreInterestingPID
...Respostas:
Envolva seu comando em um script que o notificará quando terminar.Se você tem um servidor SMTP disponível que aceita e-mails enviados do seu servidor, você pode usá-lo.
O exemplo abaixo será executado
your-command
, capturará sua saída e stderr em um arquivo e, em seguida, usarámalix
para enviar os resultados. Certamente há uma maneira muito melhor de garantir que o arquivo capturado pela saída seja exclusivo do que usar o$$
pseudovariável (talvez use uma rotina que gere uma sequência aleatória).Se você deseja algo que permita especificar uma fila de comandos, consulte o Spooler de Tarefas (
apt-get install tsp
no Debian), que permite adicionar e excluir comandos de uma fila e acredito que pode enviar por e-mail a saída deles.Lendo sua pergunta com mais cuidado ... parece que você está tratando o que a conexão SSH está entrando / saindo como um fluxo de E / S bruto.
O SSH fornece um canal criptografado e possui alguns recursos para encaminhamento de porta, e não muito mais. A coisa típica conectada a esse tubo é uma concha que normalmente espera um usuário interativo do outro lado.
Eu acho que as chaves de uso único podem alcançar o que você está tentando fazer com alguma facilidade, mas o mais fácil será criar um pequeno script de wrapper que faça isso:
e, em seguida, procure a cadeia de caracteres
==== Command Output Finished ====
em suas rotinas de E / S para determinar onde estão os limites entre as saídas do comando. Obviamente, você deve escolher algo que não possa ser parte de uma saída válida para um comando. Um esquema mais elaborado é possível.O SMTP faz algo semelhante com os cabeçalhos de limite.
fonte
find -type f -exec chmod 664
que leva 0,001 segundos ou mais. Quando abro uma conexão SSH para cada comando, eles acabam levando vários segundos cada, o que torna meu script de implantação lento. Envolvendo servidores SMTP e-mail provavelmente não vai consertar isso ...cat list_of_command | ssh ...
) #; echo "$? c8m2js7a9...
após cada comando enviado ao servidor e usá-la para saber quando o comando foi concluído e ler o status de saída. Eu só esperava que talvez houvesse uma solução mais elegante, como a execução de comandos, como de costume, que estão sendo executados de forma transparente no servidor remoto.Se você mantiver a solução de executar cada comando em uma sessão SSH separada, poderá acelerar o tempo necessário para iniciar cada sessão usando uma conexão já aberta. Isso significa que você só precisa pagar a sobrecarga da conexão uma vez, agilizando o início das sessões subseqüentes.
A maneira mais simples de configurá-lo é abrindo a primeira conexão com isso:
Em seguida, abra cada conexão subsequente com:
Há mais informações na página de
ssh_config
manual emControlMaster
eControlPath
, ou online aqui e aqui .fonte