December 30 2021, 14:47#

SSH dans une boucle while en Shell

J'ai eu un cas d'école intéressant. A l'aide d'un script Shell, je cherchais à boucler sur une liste de serveurs contenue dans un fichier hosts.txt pour y exécuter des commandes via SSH.

while read host
do
    ssh $host 'uname -a'
done < hosts.txt

Sauf que la boucle prenait fin après la première itération. J'ai mis un peu de temps à comprendre ce qui se passait, mais finalement l'explication est logique.

  1. La boucle while prend en entrée (< stdin) le contenu du fichier hosts.txt.
  2. Ensuite, SSH prend tout le reste de ce qui se trouve dans stdin.
  3. A la fin de la première itération, il n'y a donc plus rien dans stdin et la boucle prend fin.

La solution est dans le man de SSH

-n      Redirects stdin from /dev/null (actually, prevents reading
        from stdin).  This must be used when ssh is run in the back‐
        ground.  A common trick is to use this to run X11 programs on
        a remote machine.  For example, ssh -n shadows.cs.hut.fi
        emacs & will start an emacs on shadows.cs.hut.fi, and the X11
        connection will be automatically forwarded over an encrypted
        channel.  The ssh program will be put in the background.
        (This does not work if ssh needs to ask for a password or
        passphrase; see also the -f option.)

Cela fonctionnera mieux ainsi

while read host
do
    ssh -n $host 'uname -a'
done < hosts.txt

Tags : shell unix ssh