Aller au contenu
Administration Linux medium

Exécuter des commandes distantes via SSH

9 min de lecture

Une connexion SSH n’implique pas d’ouvrir un shell interactif. En passant une commande directement à ssh, vous pouvez interroger, modifier, redémarrer des services ou collecter des informations sur des dizaines de serveurs sans jamais ouvrir un terminal distant.

C’est la base de l’automatisation système et un objectif LFCS (domaine Networking — “Use SSH in automation and scripting”).

Cette technique s’utilise dès que vous devez agir sur un serveur distant sans ouvrir de session interactive : vérifier l’espace disque après un déploiement, redémarrer un service, collecter des métriques sur plusieurs machines à la fois, ou exécuter un script de provisionnement sans le copier au préalable. C’est aussi le fondement de l’automatisation avec des outils comme Ansible, qui ne fait rien d’autre qu’encapsuler des commandes SSH.


  • Lancer une commande sur un serveur sans session interactive
  • Combiner ssh avec des pipes pour traiter les données à la volée
  • Exécuter des commandes qui demandent sudo à distance
  • Écrire une boucle multi-serveurs pour des opérations batch
  • Passer des scripts locaux à un serveur distant via stdin
  • Diagnostiquer les cas où la commande distante échoue silencieusement

La syntaxe de base est ssh [options] user@hôte "commande" :

Fenêtre de terminal
# Lire les 5 dernières lignes des logs d'authentification
ssh bob@192.168.1.10 "tail -5 /var/log/auth.log"
# Vérifier l'espace disque
ssh bob@192.168.1.10 "df -h /"
# Voir les processus qui tournent
ssh bob@192.168.1.10 "ps aux | grep nginx"

Le résultat s’affiche directement dans votre terminal local. Pas de session, pas de prompt distant.


SSH peut s’insérer dans des pipelines shell ordinaires.

Fenêtre de terminal
# Récupérer /etc/hosts distant et filtrer les lignes web
ssh bob@192.168.1.10 "cat /etc/hosts" | grep web
Fenêtre de terminal
# Compresser localement et décompresser à distance (alternative à rsync)
tar czf - /data/backups | ssh bob@192.168.1.10 "tar xzf - -C /restore/"

Lire plusieurs fichiers distants avec des wildcards

Section intitulée « Lire plusieurs fichiers distants avec des wildcards »
Fenêtre de terminal
# Les wildcards doivent être entre guillemets pour être évalués à distance
ssh bob@192.168.1.10 "cat /var/log/nginx/*.log" | grep "500"

sudo sur certains systèmes exige un terminal (TTY). L’option -t alloue un pseudo-TTY :

Fenêtre de terminal
ssh -t bob@192.168.1.10 "sudo systemctl restart nginx"

Sans -t, vous obtenez : sudo: a terminal is required to read the password

Fenêtre de terminal
# Passer un script à exécuter avec sudo
cat script_local.sh | ssh -t bob@192.168.1.10 "sudo bash"

Plutôt que de copier un script sur le serveur, passez-le directement via stdin :

Fenêtre de terminal
# Exécuter un script local sur le serveur distant
ssh bob@192.168.1.10 "bash -s" < mon_script.sh

Avec des arguments :

Fenêtre de terminal
ssh bob@192.168.1.10 "bash -s" < mon_script.sh -- --env production --dry-run

Fenêtre de terminal
for host in web1 web2 web3 db1; do
echo "=== $host ==="
ssh bob@$host "uptime && df -h /"
done
Fenêtre de terminal
# servers.txt contient un hôte par ligne
while read host; do
echo "=== $host ==="
ssh bob@$host "free -h | grep Mem"
done < servers.txt
Fenêtre de terminal
echo "HOST,UPTIME,MEMORY_FREE,DISK_FREE"
for host in web1 web2 web3; do
ssh bob@$host "echo -n '${host},'; uptime | awk '{print \$(NF-2)}' | tr -d ','; echo -n ','; free -m | awk '/Mem/{print \$4}'; df -h / | awk 'NR==2{print \$4}'"
done

ssh transmet le code de retour de la commande distante — exploitable dans vos scripts :

Fenêtre de terminal
if ssh bob@192.168.1.10 "systemctl is-active nginx" > /dev/null 2>&1; then
echo "nginx actif sur 192.168.1.10"
else
echo "ALERTE : nginx inactif sur 192.168.1.10"
fi

Quitter immédiatement si une commande échoue dans une boucle :

Fenêtre de terminal
set -e
for host in web1 web2 web3; do
ssh bob@$host "test -f /var/lock/deploy.lock && exit 1 || true"
done

Combinaison utile : se connecter à un serveur intermédiaire pour atteindre une cible cachée :

Fenêtre de terminal
# Via ProxyJump en one-liner — commande sur un serveur de prod accessible via bastion
ssh -J bob@bastion.example.com bob@10.0.1.15 "systemctl status app"

SymptômeCause probableAction
sudo: a terminal is requiredsudo exige un TTYAjouter -t à la commande ssh
La commande s’exécute localementGuillemets oubliés autour de la commandeEntourer la commande de "..."
bash: commande: not found — hors sessionVariables PATH différentes en mode non-interactifUtiliser le chemin absolu ou bash -l -c "..."
Code de retour toujours 0ssh retourne 0 même si la commande a échouéVérifier la sortie d’erreur ; tester echo $? à distance
Commande bloquée sans finProgramme distant attend une entréeAjouter -n pour désactiver stdin : ssh -n ...

  • ssh user@host "commande" exécute sans ouvrir de session — la commande doit être entre guillemets
  • -t alloue un pseudo-TTY nécessaire pour sudo interactif
  • bash -s < script.sh exécute un script local à distance sans le copier
  • Le code de retour de la commande distante est transmis par SSH — utilisez-le dans vos scripts
  • Pour du batch à grande échelle, ControlMaster ou Ansible sont plus adaptés que les boucles for

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn