web-dev-qa-db-fra.com

Comment exécuter de nombreuses commandes à distance SSH, sur plusieurs machines, par lots?

J'utilise SSH pour exécuter certaines commandes sur plusieurs ordinateurs distants dans une boucle for. Il exécute les mêmes commandes pour une liste d'adresses IP. Certaines adresses IP pouvant être inaccessibles, j'ai utilisé l'option ConnectTimeout.

Cependant, mon script ne fonctionnait pas comme je le voulais. En fait, il s'est bloqué à la première adresse IP inaccessible au lieu d'abandonner et d'essayer la prochaine adresse IP de ma liste.

Voici la partie pertinente de mon script:

for ip in ${IP} ; do
    ssh  -o BatchMode=yes \
         -o StrictHostKeyChecking=no \
         -o ConnectTimeout=10 \
         -l ${USERNAME} \
         ${SCRIPT_Host} \
         "${COMMAND} -i $ip || echo timeout" \
         >> ./myscript.out
done

Cela fonctionne très bien pour les adresses IP accessibles, mais si une adresse IP spécifique est hors service, il attend quelques instants (beaucoup plus que 10 secondes, peut-être 35 à 40 secondes) et affiche un message d'erreur sur mon terminal:

ERROR connecting : Connection timed out

Je me demande donc quelle option je n’ai pas utilisée correctement.

13
JavaRed

Votre utilisation de ConnectTimeout est correcte, il est donc difficile de comprendre pourquoi elle expire uniquement après 30 secondes ou plus.

Voici comment je voudrais changer votre script pour éviter complètement le problème de délai d'attente:

  • Utilisez GNU parallel pour vous connecter à plusieurs hôtes de destination en même temps.
  • Utilisez l'option -f dans SSH pour le traiter en arrière-plan.

Voici une solution avec GNU parallel , exécutant au maximum 50 connexions en même temps:

parallel --gnu --bg --jobs 50 \
ssh -o BatchMode=yes \
    -o StrictHostKeyChecking=no \
    -o ConnectTimeout=10 \
    -l ${USERNAME} \
    {} \
    "${COMMAND} -i {} || echo timeout" \
::: ${IP}

parallel <command> ::: <arguments> va exécuter <command> <argument> plusieurs fois en parallèle en scindant la liste <arguments>. L'espace réservé pour <argument> est {}.

Utilisez parallel --jobs n pour limiter le nombre de connexions en parallèle.

15
Sigi

Le délai de connexion correspond à la connexion déjà établie. Si la connexion reste inactive pendant quelques secondes, elle se déconnectera (si vous n’avez pas également activé le paramètre KEEP_ALIVE ssh qui empêche la connexion de tourner au ralenti).

La raison pour laquelle il faut plus de 30 secondes avant l'expiration est parce que c'est le temporisateur interne du protocole TCP qui tente de se connecter pendant cette durée et renvoie le message d'erreur indiquant qu'il ne peut pas se connecter au serveur sftp. Cela ne vient pas de ssh.

1
tsezane