Comment faire ssh avec un timeout dans un script?

173

J'exécute un script de connexion via SSH sans mot de passe sur un hôte distant. Je veux définir un délai d'expiration, de sorte que si l'hôte distant prend un temps infini à s'exécuter, je veux sortir de cette session ssh et continuer d'autres lignes dans mon script sh.

Une idée sur la façon de le faire?

utilisateur57421
la source
Cela devrait probablement être fermé pour être en ligne avec la fermeture d'un double complet de ceci comment réduire la valeur du délai d'expiration de la connexion ssh [fermé]
Murmel
Si vous avez redirigé ici uniquement pour "rester plus de temps dans votre sshsession" (question "Comment augmenter le délai de connexion SSH?"), Ce n'est pas le bon endroit . La réponse est à ce lien sur ssh-timeout .
Peter Krauss le

Réponses:

288
ssh -o ConnectTimeout=10  <hostName>

Où 10 est le temps en secondes. Ce délai d'expiration s'applique uniquement à la création de la connexion.

utilisateur57421
la source
4
ConnectTimeout définit uniquement un délai d'expiration sur la configuration de la connexion, non?
Aurélien Ooms
10
Cela ne fonctionne pas pour "l'hôte distant prend un temps infini à s'exécuter": "ssh -o ConnectTimeout = 5 host 'sleep 10'" attend 10 secondes, pas 5.
Ferry Boender
109

Utilisez le -o ConnectTimeoutet -o BatchMode=yes -o StrictHostKeyChecking=no.

ConnectTimeout empêche le script de se bloquer , BatchMode l' empêche de se bloquer avec l'hôte inconnu, YES pour l'ajouter à known_hosts et StrictHostKeyChecking ajoute automatiquement l'empreinte digitale.

**** NOTE **** Le "StrictHostKeyChecking" était uniquement destiné aux réseaux internes où vous faites confiance à vos hôtes. Selon la version du client SSH, le message «Êtes-vous sûr de vouloir ajouter votre empreinte digitale» peut entraîner le blocage du client indéfiniment (principalement les anciennes versions fonctionnant sous AIX). La plupart des versions modernes ne souffrent pas de ce problème. Si vous devez gérer des empreintes digitales avec plusieurs hôtes, je vous recommande de maintenir le fichier known_hosts avec une sorte d'outil de gestion de configuration comme puppet / ansible / chef / salt / etc.

Doug
la source
11
Non seulement ne répond -o StrictHostKeyChecking=nopas à la question, mais c'est une idée terrible si vous vous souciez de la sécurité, ce qui pourrait être la raison pour laquelle vous utilisez SSH en premier lieu.
Dolph
9
Il est bon de souligner les implications de sécurité possibles de -o StrictHostKeyChecking = no. Cependant, cela empêchera le script de se bloquer pendant l'exécution.
Doug
2
AVERTISSEMENT!!!! Comme @Dolph l'a écrit, ne l'utilisez PAS StrictHostKeyChecking=nosi vous vous souciez du tout de la sécurité. @Doug: le script ne se bloquera pas - il insistera simplement pour que vous ssh vers l'hôte distant manuellement la première fois, afin qu'il apprenne à connaître l'hôte. Mais cela vous protégera contre les attaques MITM. Veuillez modifier cette réponse pour refléter cela car il s'agit d'un conseil très dangereux en l'état. Et ce n'était même pas demandé.
johndodo
2
Mis à jour ma réponse. D'après mon expérience, certains clients peuvent se bloquer.
Doug
50

essaye ça:

timeout 5 ssh user@ip

timeout exécute la commande ssh (avec args) et envoie un SIGTERM si ssh ne revient pas après 5 secondes. pour plus de détails sur le timeout, lisez ce document : http://man7.org/linux/man-pages/man1/timeout.1.html

ou vous pouvez utiliser le paramètre de ssh:

ssh -o ConnectTimeout=3 user@ip
Lee HoYo
la source
4
Si vous recherchez cette commande sur un Mac, essayez brew install coreutilspuis utilisez gtimeout (source: stackoverflow.com/questions/3504945/timeout-command-on-mac-os-x ).
larcher
3
Cela peut ne pas faire ce que vous voulez. Considérez la commande timeout 3s ssh user@server 'sleep 5; echo blarg >> /tmp/blarg' Ceci tue le processus côté client SSH, mais / tmp / blarg est toujours modifié sur le serveur distant. Cela signifie que si vous exécutez un travail gourmand en ressources processeur sur le serveur distant, vous perdrez des processus.
Jamie Davis
1
@JamieDavis qu'en est-il de ssh user @ server 'timeout 5s sleep 10'?
FilipR
18

Vous pouvez également vous connecter avec flag

-o ServerAliveInterval = <secs>
donc le client SSH enverra un paquet nul au serveur toutes les <secs>secondes, juste pour maintenir la connexion active. Sous Linux, cela peut également être défini globalement dans /etc/ssh/ssh_configou par utilisateur dans ~/.ssh/config.

Patrizio Bertoni
la source
4
Cela ressemble à l'opposé de ce que demande la question.
Davor Cubranic
1

Si tout le reste échoue (y compris ne pas avoir la timeoutcommande), le concept de ce script shell fonctionnera:

 #!/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
la source
0

Eh bien, vous pouvez utiliser nohup pour exécuter tout ce que vous exécutez en «mode non bloquant». Vous pouvez donc continuer à vérifier si tout ce qu'il était censé exécuter, s'exécuter, sinon quitter.

nohup ./my-script-that-may-take-long-to-finish.sh &
./check-if-previous-script-ran-or-exit.sh
echo "Le script s'est terminé le 15 février 2011 à 9h20"> /tmp/done.txt

Donc, dans le second, vous vérifiez simplement si le fichier existe.

Eduardo
la source
Logique. mais, le script qui est en cours d'exécution me donne une sortie, qui est affichée sur la console .. comment vérifier si mon script précédent a fonctionné ou quitte? $? ou autre chose?
user57421
Eh bien, vous pouvez faire en sorte que ce script crée un fichier une fois terminé. J'ai ajouté le commentaire à la réponse .... grrr
Eduardo