Como fazer ssh com um tempo limite em um script?

173

Estou executando um script conectando via SSH sem senha em um host remoto. Quero definir um tempo limite, para que, se o host remoto estiver demorando um tempo infinito para executar, desejo sair dessa sessão ssh e continuar outras linhas no meu script sh.

Alguma idéia de como fazer isso?

user57421
fonte
Isso provavelmente deve ser fechado para estar em linha com o fechamento de uma duplicata completa deste como diminuir o valor de tempo limite de conexão ssh [fechada]
Murmel
Se você redirecionou aqui apenas para "ficar mais tempo na sua sshsessão" (pergunta "Como aumentar o tempo limite da conexão SSH?"), Este é o lugar errado . A resposta está neste link sobre ssh-timeout .
Peter Krauss

Respostas:

288
ssh -o ConnectTimeout=10  <hostName>

Onde 10 é o tempo em segundos. Esse tempo limite se aplica apenas à criação da conexão.

user57421
fonte
4
O ConnectTimeout define apenas um tempo limite na configuração da conexão, certo?
Aurélien Ooms
10
Na verdade, isso não funciona para "o host remoto está demorando um tempo infinito para ser executado": "ssh -o ConnectTimeout = 5 host 'sleep 10'" aguarda 10 segundos, não 5.
Ferry Boender
109

Use o -o ConnectTimeoute -o BatchMode=yes -o StrictHostKeyChecking=no.

O ConnectTimeout evita que o script seja interrompido , o BatchMode o impede com o Host desconhecido, YES para adicionar a known_hosts e StrictHostKeyChecking adiciona a impressão digital automaticamente.

**** NOTA **** O "StrictHostKeyChecking" foi projetado apenas para redes internas nas quais você confia nos hosts. Dependendo da versão do cliente SSH, o "Tem certeza de que deseja adicionar sua impressão digital" pode fazer com que o cliente seja interrompido indefinidamente (principalmente versões antigas em execução no AIX). A maioria das versões modernas não sofre com esse problema. Se você precisar lidar com impressões digitais com vários hosts, recomendo manter o arquivo known_hosts com algum tipo de ferramenta de gerenciamento de configuração, como puppet / ansible / chef / salt / etc.

Doug
fonte
11
Não apenas -o StrictHostKeyChecking=nonão aborda a questão, mas é uma péssima idéia se você se preocupa com segurança, que pode ser a razão pela qual você está usando o SSH em primeiro lugar.
21415 Dolph
9
É bom ressaltar as possíveis implicações de segurança de -o StrictHostKeyChecking = no. No entanto, impedirá que o script seja interrompido durante a execução.
Doug
2
AVISO!!!! Como o @Dolph escreveu, NÃO use StrictHostKeyChecking=nose você se preocupa com segurança. @ Doug: o script não travará - apenas insistirá que você faça o ssh para o host remoto manualmente pela primeira vez, para que ele conheça o host. Mas ele irá protegê-lo contra ataques MITM. Edite esta resposta para refletir isso, pois é um conselho muito perigoso. E nem foi solicitado.
Johndodo
2
Atualizei minha resposta. De acordo com minha experiência, isso pode causar a interrupção de alguns clientes.
Doug
50

tente isto:

timeout 5 ssh user@ip

timeout executa o comando ssh (com args) e envia um SIGTERM se o ssh não retornar após 5 segundos. para obter mais detalhes sobre o tempo limite, leia este documento: http://man7.org/linux/man-pages/man1/timeout.1.html

ou você pode usar o param do ssh:

ssh -o ConnectTimeout=3 user@ip
Lee HoYo
fonte
4
Se você está procurando esse comando em um Mac, tente brew install coreutilse use gtimeout (fonte: stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x ).
larcher
3
Isso pode não fazer o que você deseja. Considere o comando timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' Isso mata o processo no lado do cliente SSH, mas / tmp / blarg ainda é modificado no servidor remoto. Isso significa que, se você estiver executando um trabalho descontrolado com muita CPU no servidor remoto, irá vazar os processos.
Jamie Davis
1
@JamieDavis que tal ssh user @ server 'timeout 5s sleep 10'?
FilipR
18

Você também pode se conectar com a bandeira

-o ServerAliveInterval = <seg>
portanto, o cliente SSH enviará um pacote nulo ao servidor a cada <secs>segundo, apenas para manter a conexão ativa. No Linux, isso também pode ser definido globalmente /etc/ssh/ssh_configou por usuário ~/.ssh/config.

Patrizio Bertoni
fonte
4
Isso soa como o oposto do que a pergunta solicita.
Davor Cubranic
1

Se tudo mais falhar (incluindo não ter o timeoutcomando), o conceito neste script de shell funcionará:

 #!/bin/bash
 set -u
 ssh $1 "sleep 10 ; uptime" > /tmp/outputfile 2>&1 & PIDssh=$!
 Count=0
 while test $Count -lt 5 && ps -p $PIDssh > /dev/null
 do
    echo -n .
    sleep 1
    Count=$((Count+1))
 done
 echo ""

 if ps -p $PIDssh > /dev/null
 then
    echo "ssh still running, killing it"
    kill -HUP $PIDssh
 else
    echo "Exited"
 fi
Philip Kearns
fonte
0

Bem, você pode usar o nohup para executar o que estiver executando no 'modo sem bloqueio'. Portanto, você pode apenas verificar se o que deveria executar, executou ou sair.

nohup ./my-script-that-may-take-long-to-finish.sh &
./check-if-previous-script-ran-or-exit.sh
echo "Script finalizado em 15 de fevereiro de 2011, 09:20"> /tmp/done.txt

Então, no segundo, você apenas verifica se o arquivo existe.

Eduardo
fonte
Faz sentido. mas, o script que está sendo executado me fornece alguma saída, exibida no console. como verificar se meu script anterior foi executado ou encerrado? $? ou qualquer outra coisa?
user57421
Bem, você pode fazer esse script criar um arquivo quando terminar. Eu adicionei o comentário à resposta .... grrr
Eduardo