Exécuter des commandes distantes avec ssh

Le lancement de commandes distantes avec ssh semble anodin, pourtant il est possible de se retrouver confronté à des problèmes d’exécution ou de déconnexions intempestives. Cette article vise à se prémunir contre ce genre d’aléas notamment au travers des outils screen et scp.

Le contenu suivant déroule progressivement un ensemble de cas d’utilisations et leurs limites. Tout commence par un exemple, puis sa limite qui force à adopter une nouvelle solution, et ainsi de suite … Pour illustrer ces exemples l’usagé mikael est utilisé pour se connecter au serveur mikael-flora.fr.

Exécution d’une commande distante via ssh

Créer un fichier dans le répertoire /tmp/ ne pose pas de problème […] :

ssh mikael@mikael-flora.fr touch /tmp/test.txt

[…] Mais certaines commandes ont besoin d’être exécutées au sein d’un terminal pour fonctionner. Par exemple l’utilisation de la commande sudo provoque une erreur :

ssh mikael@mikael-flora.fr sudo ifconfig
sudo: pas de tty présent et pas de programme askpass spécifié

Pour résoudre le problème il faut allouer un pseudo terminal avec l’option -t de la commande ssh :

ssh -t mikael@mikael-flora.fr sudo ifconfig
[sudo] password for mikael:
# [...]

Exécution d’une commande utilisant des opérateurs

Une autre commande qui ne devrait pas poser de problème […] :

ssh mikael@mikael-flora.fr echo "Hello World!" >> /tmp/test.txt

[…] Pourtant le résultat obtenu n’est pas celui attendu :

ssh mikael@mikael-flora.fr cat /tmp/test.txt
cat: /tmp/test.txt: Aucun fichier ou dossier de ce type
# En fait la sortie standard a etait redirigee
# vers le fichier /tmp/test.txt du poste local :
cat /tmp/test.txt
Hello World!

La solution :

ssh mikael@mikael-flora.fr 'echo "Hello World!" >> /tmp/test.txt'

Exécution de plusieurs commandes

Il serait tout à fait possible d’exécuter plusieurs commandes les unes à la suite des autres via une succession de connexions ssh ou au sein d’une seule et même session :

ssh mikael@mikael-flora.fr touch /tmp/test.txt
ssh mikael@mikael-flora.fr 'chmod 777 /tmp/test.txt'
# ou :
ssh mikael@mikael-flora.fr 'touch /tmp/test.txt && chmod 777 /tmp/test.txt'
# mais aussi :
ssh mikael@mikael-flora.fr 'touch /tmp/test.txt
> chmod 777 /tmp/test.txt'

Cependant aucune de ces solutions n’est conseillée :

  • la première initie plusieurs connexions ssh ce qui est une perte de temps et de ressources système/réseau
  • ces solutions atteignent rapidement leur limite dès qu’il faut enchaîner les instructions (jongler entre les guillemets, les variables, les structures conditionnelles …)

Une possibilité consiste à écrire toutes les instructions dans un fichier local et à le lire depuis l’entrée standard de l’interpréteur de commandes de la machine distante :

ssh mikael@mikael-flora.fr "bash -s" < ./script.bash

Par contre si une déconnexion a lieu, le travail s’arrête immédiatement. Donc, au mieux il faudra reprendre là ou il en était rendu, au pire le système est compromis …

Se prémunir contre les déconnexions avec scp et screen

La commande scp permet de copier des fichiers sur des machines distantes via ssh. Dans notre cas elle servirait à transférer un script à exécuter.

La commande screen permet de gérer de multiple sessions au sein d’une console. Elle peut créer ou supprimer des consoles virtuelles tout en offrant à l’utilisateur la possibilité de s’en détacher ou de s’en rattacher. Ainsi il devient facile d’imaginer qu’une commande lancée dans un screen continura d’être exécutée même en cas de perte de connexion. De plus elle pourrait même être récupée si elle est en attente d’une action de la part de l’usager.

Ces deux commandes associés donnent :

# transfert du script a executer
scp mikael@mikael-flora.fr script.bash /tmp/script.bash
# execution du script dans un screen detache
ssh mikael@mikael-flora.fr screen -dm /tmp/script.bash

Si pour une raison ou une autre le screen ne se termine pas, il est possible de se rattacher à celui-ci :

# se connecter sur le serveur
ssh mikael@mikael-flora.fr
# identifier le screen
screen -ls
There is a screen on:
	27915..mikael-flora.fr	(29/10/2017 20:23:34)	(Detached)
1 Socket in /var/run/screen/S-mikael.
# se rattacher au screen 27915
screen -r 27915

Pour conclure

L’idéal est d’utiliser les commandes les plus adaptées à ce que l’on souhaite faire :

# commande qui ne represente pas de risque en cas de déconnexion
ssh <user>@<hostname> <command>
# commande qui ne represente pas de risque en cas de déconnexion
# mais qui necessite la presence d'un tty
ssh -t <user>@<hostname> <command>
# commande qui peut representer un risque
ssh <user>@<hostname> screen -dm <command>
# plusieurs commandes au sein d'un script
scp <user>@<hostname> </local/script> </remote/script>
ssh <user>@<hostname> screen -dm </remote/script>
Vous avez aimé ?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

onze + douze =