Come fare ssh con un timeout in uno script?


173

Sto eseguendo uno script di connessione tramite SSH senza password su un host remoto. Voglio impostare un timeout, in modo che se l'host remoto impiega un tempo infinito per essere eseguito, voglio uscire da quella sessione ssh e continuare altre righe nel mio script sh.

Qualche idea su come farlo?


Questo dovrebbe probabilmente essere chiuso per essere in linea con la chiusura di un duplicato completo di questo come ridurre il valore di timeout della connessione ssh [chiuso]
Murmel

Se hai reindirizzato qui solo per "rimanere più tempo nella sshsessione" (domanda "Come aumentare il timeout della connessione SSH?"), Questo è il posto sbagliato . La risposta è a questo link su ssh-timeout .
Peter Krauss,

Risposte:


288
ssh -o ConnectTimeout=10  <hostName>

Dove 10 è il tempo in secondi. Questo timeout si applica solo alla creazione della connessione.


4
ConnectTimeout imposta solo un timeout sull'impostazione della connessione, giusto?
Aurélien Ooms,

10
Questo in realtà non funziona per "l'host remoto impiega un tempo infinito a funzionare": "ssh -o ConnectTimeout = 5 host 'sleep 10'" attende 10 secondi, non 5.
Ferry Boender

109

Utilizzare il -o ConnectTimeoute -o BatchMode=yes -o StrictHostKeyChecking=no.

ConnectTimeout blocca lo script, BatchMode lo blocca con Host sconosciuto, SÌ da aggiungere a known_hosts e StrictHostKeyChecking aggiunge automaticamente l'impronta digitale.

**** NOTA **** "StrictHostKeyChecking" era destinato esclusivamente a reti interne in cui ti fidi degli host. A seconda della versione del client SSH, "Sei sicuro di voler aggiungere la tua impronta digitale" può causare il blocco del client a tempo indeterminato (principalmente versioni precedenti in esecuzione su AIX). La maggior parte delle versioni moderne non soffre di questo problema. Se devi gestire le impronte digitali con più host, ti consiglio di mantenere il file known_hosts con una sorta di strumento di gestione della configurazione come puppet / ansible / chef / salt / etc.


11
Non solo -o StrictHostKeyChecking=nonon affronti la domanda, ma è una pessima idea se ti preoccupi della sicurezza, che potrebbe essere il motivo per cui stai usando SSH in primo luogo.
Dolph,

9
È bene sottolineare le possibili implicazioni sulla sicurezza di -o StrictHostKeyChecking = no. Tuttavia, impedirà che lo script si blocchi durante l'esecuzione.
Doug,

2
AVVERTIMENTO!!!! Come ha scritto @Dolph, NON usare StrictHostKeyChecking=nose ti interessa la sicurezza. @Doug: lo script non si bloccherà - insisterà semplicemente sul fatto che si ssh all'host remoto manualmente la prima volta, in modo da conoscere l'host. Ma ti proteggerà dagli attacchi MITM. Modifica questa risposta per riflettere questo dato che è un consiglio molto pericoloso così com'è. E non è stato nemmeno chiesto.
johndodo,

2
Aggiornato la mia risposta. Dalla mia esperienza, può causare l'impiccagione di alcuni client.
Doug,

50

prova questo:

timeout 5 ssh user@ip

timeout esegue il comando ssh (con args) e invia un SIGTERM se ssh non ritorna dopo 5 secondi. per maggiori dettagli sul timeout, leggi questo documento : http://man7.org/linux/man-pages/man1/timeout.1.html

oppure puoi usare il parametro di ssh:

ssh -o ConnectTimeout=3 user@ip

4
Se stai cercando questo comando su un Mac, prova brew install coreutilse poi usa gtimeout (fonte: stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x ).
Larcher,

3
Questo potrebbe non fare quello che vuoi. Considera il comando timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' Questo interrompe il processo sul lato client SSH, ma / tmp / blarg viene comunque modificato sul server remoto. Ciò significa che se si sta eseguendo un lavoro ad alta intensità di CPU in fuga sul server remoto, si perderanno i processi.
Jamie Davis,

1
@JamieDavis che ne dici di ssh user @ server 'timeout 5s sleep 10'?
FilipR,

18

Puoi anche connetterti con flag

-o ServerAliveInterval = <secs>
così il client SSH invierà un pacchetto null al server ogni <secs>secondo, solo per mantenere attiva la connessione. In Linux questo potrebbe anche essere impostato a livello globale /etc/ssh/ssh_configo per utente ~/.ssh/config.


4
Sembra il contrario di ciò che la domanda richiede.
Assapora Cubranic il

1

Se tutto il resto fallisce (incluso non avere il timeoutcomando) il concetto in questo script di shell funzionerà:

 #!/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

0

Bene, potresti usare nohup per eseguire qualunque cosa tu stia eseguendo in "modalità non bloccante". Quindi puoi semplicemente controllare se tutto ciò che doveva funzionare, correre, altrimenti uscire.

nohup ./my-script-that-may-take-long-to-finish.sh &
./check-if-previous-script-ran-or-exit.sh
echo "Script terminato il 15 febbraio 2011, 9:20"> /tmp/done.txt

Quindi nella seconda controlli solo se il file esiste.


Ha senso. ma, lo script in esecuzione mi dà un po 'di output, che viene visualizzato sulla console .. come verificare se il mio script precedente è stato eseguito o uscire? $? o qualsiasi altra cosa ?
user57421

Bene, potresti fare in modo che lo script crei un file al termine. Ho aggiunto il commento alla risposta .... grrr
Eduardo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.