SSD Nodes Learn 🎉 VPS dès $5.50/mois
Guides Matt ConnorPar Matt Connor

Commande watch Linux : options et pièges à connaître

La commande watch répète une commande toutes les 2 secondes par défaut. Réglez l’intervalle, surlignez les différences, quittez au changement et protégez les pipes.

Ce que fait la commande watch

La commande watch réexécute une autre commande à intervalle fixe et redessine sa sortie au même endroit à l’écran. L’intervalle par défaut est de deux secondes. Utilisez-la lorsque vous attendez qu’une valeur évolue : un disque qui se remplit, un conteneur qui termine son initialisation, un renouvellement de certificat qui aboutit ou une file d’attente qui se vide.

watch fait partie de procps-ng et est déjà installé sur un VPS Ubuntu ou Debian fraîchement déployé, dans le cadre du paquet procps. Vérifiez votre version avant de vous fier aux options ci-dessous, car deux options utiles sont récentes.

watch --version

Sur Ubuntu 24.04, cette commande affiche une ligne similaire à watch from procps-ng 4.0.4. Voici maintenant l’exemple utile le plus simple.

watch df -h /

L’écran est effacé et affiche une ligne d’en-tête, une ligne vide, puis la sortie de df -h / :

Every 2.0s: df -h /                          server1: Sun Aug  9 10:21:44 2026

À gauche figurent l’intervalle et la commande exacte exécutée par watch. À droite figurent le nom d’hôte et l’heure actuelle. L’horloge est la partie la plus utile : elle confirme que l’écran continue d’être actualisé lorsque les valeurs affichées en dessous ne changent pas. Appuyez sur Ctrl+C pour quitter.

watch dessine une seule vue adaptée à la taille du terminal. Les lignes longues sont renvoyées à la ligne ; -w les tronque à la place, et tout ce qui dépasse la dernière ligne n’est pas affiché. La vue ne possède pas de défilement, car chaque cycle écrase le précédent. Cette contrainte détermine à elle seule la plupart des usages adaptés à watch.

À quelle fréquence watch doit-il réexécuter la commande ?

Deux secondes est uniquement la valeur par défaut. Choisissez l’intervalle en fonction de la vitesse à laquelle la valeur change et du coût d’une exécution.

  • -n 0.5 pour les compteurs qui évoluent en continu, comme ss -s ou le nombre d’octets d’une interface. Le plus petit intervalle accepté par watch est de 0.1 seconde.
  • -n 30 ou -n 60 pour les disques et les certificats. Un système de fichiers qui se remplit en une journée n’a pas besoin de trente affichages par minute.

watch exécute la commande, attend qu’elle se termine, puis attend l’intervalle indiqué. La durée d’exécution s’ajoute donc à l’intervalle : une commande qui prend huit secondes avec -n 2 produit un affichage toutes les dix secondes et sollicite la machine pendant toute cette durée. Ajoutez -p (--precise) pour que watch tente plutôt de démarrer une exécution toutes les secondes indiquées par l’intervalle, en mesurant le délai entre le début de deux exécutions successives.

Si vous voulez toujours utiliser une autre valeur par défaut, exportez WATCH_INTERVAL dans le profil de votre shell. Une option -n explicite reste prioritaire. Exécutez watch --help pour vérifier que votre build lit cette variable.

Mettez en évidence les changements avec -d

Lire un long bloc de texte identique pour trouver le seul champ qui a changé de place est fastidieux. -d (--differences) le fait pour vous.

watch -n 30 -d 'df -h / /var'

Les caractères qui diffèrent de la trame précédente sont affichés en vidéo inversée. Ainsi, la cellule Use% s’allume dès qu’elle change de place, tandis que tout le reste reste inchangé. Si /var n’est pas un système de fichiers distinct, le système de fichiers root apparaît deux fois. C’est un moyen rapide de comprendre comment le serveur a été partitionné.

La comparaison est positionnelle. Les lignes de la nouvelle trame sont comparées à celles de l’ancienne, caractère par caractère. Une sortie dont la largeur des colonnes change sera presque entièrement mise en évidence. Préférez donc les commandes dont la présentation reste stable. Les versions actuelles de procps-ng acceptent également watch --differences=permanent. Cette option conserve la mise en évidence de chaque position ayant déjà changé, au lieu de ne montrer que le changement le plus récent. Vérifiez ce comportement avec watch --help avant de vous y fier.

Comment faire pour que watch se termine lorsque la sortie change ?

-g (--chgexit) arrête watch dès que la sortie diffère de celle de l’exécution précédente. L’invite de commande réapparaît, ce qui vous permet de placer une autre commande sur la même ligne.

watch -n 10 -g 'systemctl is-active myapp' ; echo 'state changed'

C’est l’option qui transforme watch en outil permettant de savoir quand un déploiement est terminé. Elle comporte toutefois un piège qui concerne tout le monde : la comparaison porte sur toute la sortie. Une horloge ou un PID (identifiant de processus) présent dans celle-ci change donc dès le premier rafraîchissement, et watch se termine immédiatement. systemctl status myapp affiche le temps écoulé et l’utilisation mémoire ; utiliser -g avec cette commande est donc inutile. Réduisez la commande au seul élément stable que vous attendez : c’est ce que fournit systemctl is-active.

Les versions plus récentes de procps-ng ajoutent le test inverse, --equexit <cycles>, qui se termine lorsque la sortie reste identique pendant ce nombre de cycles. Il répond à la question « dites-moi quand tout est devenu silencieux ». Vérifiez avec watch --help, car les anciennes versions ne disposent pas de cette option.

Pourquoi watch ignore-t-il mon pipe et mon glob ?

C’est l’erreur que tout le monde rencontre une fois. La cause se trouve dans votre shell, pas dans watch.

watch docker compose ps | grep web

Votre shell interactif lit toute la ligne avant d’exécuter quoi que ce soit. Il découpe ensuite cette ligne au niveau du pipe. Il lance watch docker compose ps et redirige la sortie d’écran de watch vers grep. watch n’écrit alors plus dans un terminal. L’affichage est donc cassé ou vide, et grep filtre la sortie de redessin au lieu d’afficher la liste des conteneurs.

Mettez toute la pipeline entre guillemets pour qu’elle soit transmise comme un seul argument.

watch 'docker compose ps | grep web'

watch transmet cette chaîne à sh -c, et ce shell exécute la pipeline une fois par cycle. Les globs suivent la même règle, avec un effet moins visible.

watch ls -l /var/log/*.log
watch 'ls -l /var/log/*.log'

La première ligne développe le glob une seule fois, dans votre shell, au moment où vous appuyez sur Entrée. watch réutilise ensuite une liste figée de noms de fichiers. Un fichier de log créé une minute plus tard n’apparaît donc jamais. La deuxième ligne transmet le glob à watch, qui le développe dans sh à chaque cycle. Les nouveaux fichiers apparaissent ainsi automatiquement.

Les guillemets déterminent également le moment où une variable ou une substitution de commande est évaluée. watch "echo $(date)" exécute date une fois, dans votre shell, puis affiche indéfiniment cette chaîne figée. watch 'echo $(date)' exécute date à chaque cycle. Les guillemets simples signifient « plus tard ». Les guillemets doubles signifient « maintenant ».

Cette sh -c a deux autres conséquences :

  • Les alias et les fonctions shell n’existent pas à l’intérieur. watch ll échoue avec sh: 1: ll: not found, car sh -c ne lit jamais votre .bashrc. Écrivez la commande complète ou indiquez le chemin absolu vers un binaire qui se trouve uniquement dans votre PATH interactif.
  • La sortie d’erreur standard mérite d’être capturée. Placez 2>&1 entre les guillemets lorsque vous voulez afficher les erreurs dans le cadre plutôt que de les disperser par-dessus.

Lorsque les guillemets deviennent difficiles à gérer, -x (--exec) exécute directement la commande au lieu de passer par sh -c. Les arguments contenant des espaces sont plus simples à gérer. En revanche, les pipes et les globs cessent complètement de fonctionner, car aucun shell ne les interprète.

Les privilèges suivent la même logique, car watch est un processus ordinaire. watch 'sudo ss -tulpn' affiche une invite de mot de passe que vous ne pouvez ni voir ni utiliser. Exécutez plutôt sudo watch 'ss -tulpn' et rappelez-vous que toute la boucle s’exécute alors en tant que root jusqu’à ce que vous appuyiez sur Ctrl+C.

Quatre éléments à surveiller sur un VPS

Un disque qui se remplit

watch -n 30 -d 'df -h / /var'

df demande au kernel des valeurs qu’il contient déjà. Il est donc suffisamment peu coûteux pour être répété indéfiniment. Ce n’est pas le cas de du -sh /var/log, qui parcourt tous les fichiers de l’arborescence à chaque cycle. Avec watch, il lit le disque en continu et ralentit la machine que vous essayez de diagnostiquer. Exécutez du une fois, ou utilisez ncdu, puis laissez df sous surveillance pour vérifier si le nombre continue d’augmenter.

Un conteneur qui redémarre en boucle

cd /srv/myapp
watch -n 5 -d 'docker compose ps'

La colonne d’état indique depuis combien de temps chaque conteneur fonctionne. Un conteneur pris dans une boucle de crash revient sans cesse à « Up 2 seconds », et -d le montre immédiatement. Changez d’abord de répertoire, car watch reprend le répertoire de travail du shell qui l’a lancé et docker compose a besoin du répertoire du projet. watch vous indique qu’un redémarrage a lieu. docker compose logs -f web vous en indique la cause. Une fois la cause identifiée, encodez la réponse dans un healthcheck Compose qui redémarre le conteneur à votre place, afin que personne n’ait à rester devant un écran.

Le renouvellement d’un certificat

sudo -i
watch -n 60 -g 'openssl x509 -noout -enddate -in /etc/letsencrypt/live/example.com/fullchain.pem'

La commande affiche une ligne, notAfter=Nov 7 09:14:22 2026 GMT, et rien d’autre. -g se déclenche donc exactement lorsque le fichier est remplacé par un certificat renouvelé. Les fichiers sous /etc/letsencrypt/live ne sont lisibles que par root, raison pour laquelle cette commande est exécutée dans un shell root. Notez que cette surveillance porte sur le certificat présent sur le disque. Un serveur web en fonctionnement conserve l’ancien certificat en mémoire jusqu’à son rechargement. Vérifiez donc le certificat réellement servi avec echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate et n’exécutez pas cette commande toutes les deux secondes contre un hôte public. Le renouvellement lui-même relève de un service et un timer systemd, et systemctl list-timers indique la date de sa prochaine exécution.

Une file qui se vide

watch -n 15 'postqueue -p | tail -n 1'

Cette commande affiche une ligne récapitulative telle que -- 24 Kbytes in 6 Requests., ou Mail queue is empty une fois la file vide. Le même principe fonctionne pour toute file dont vous pouvez compter les éléments : watch -n 5 'find /srv/queue/incoming -type f | wc -l'.

C’est ici que watch atteint sa limite. Il compare une frame à la précédente et ne peut pas tester une condition. Il ne peut donc jamais vous indiquer que « le nombre a atteint zéro ». Une simple boucle shell le permet, en utilisant la substitution de commande pour récupérer le nombre à chaque passage :

until [ "$(find /srv/queue/incoming -type f | wc -l)" -eq 0 ]; do sleep 5; done; echo 'queue drained'

Quand la commande watch n’est pas le bon outil

watch réexécute votre commande sans conserver le résultat de l’exécution précédente et sans savoir ce que fait cette commande. Cela convient pour df. Dans quatre situations, ce n’est pas le bon outil.

  • Journaux. watch redessine une vue fixe. Les lignes qui apparaissent puis défilent entre deux cycles sont perdues. Utilisez journalctl -fu nginx ou tail -f : ces outils affichent les nouvelles lignes au fur et à mesure de leur écriture.
  • Commandes coûteuses. du -sh / ou une requête sur une base de données très sollicitée devient une charge permanente en arrière-plan, quelle que soit la fréquence choisie, car watch la relance à chaque cycle.
  • Toute opération avec des effets de bord. Une commande qui écrit, envoie une requête, redémarre un service ou installe un paquet répétera cette opération à chaque cycle. Un curl vers une API toutes les deux secondes représente 43,200 requêtes par jour. C’est ainsi qu’une clé d’API gratuite est suspendue.
  • Vérifications de longue durée. watch s’exécute dans votre terminal et s’arrête avec votre session. Il n’envoie aucune alerte et ne conserve aucun historique après la fermeture de votre ordinateur portable. Pour cela, utilisez un véritable outil de supervision de l’état, comme Uptime Kuma, ou une vérification planifiée qui s’exécute sur le serveur.

La limite se résume à la durée. watch sert à attendre pendant dix minutes qu’un événement précis se produise. Tout ce qui doit continuer à être vérifié demain doit utiliser un timer planifié ou un véritable outil de supervision.

Exécuter watch dans tmux via SSH

Avec SSH, watch n’est pas plus durable que la connexion. Lorsque la liaison est interrompue, votre shell reçoit SIGHUP et arrête watch avec elle. tmux résout ce problème et rend watch réellement utile sur un serveur distant.

tmux new -As ops
watch -n 30 -d 'df -h /'

Appuyez sur Ctrl+b, puis sur d pour détacher la session. La boucle continue de s’exécuter sur le serveur. Reconnectez-vous ensuite avec tmux attach -t ops : l’affichage continue de se mettre à jour et l’horloge de l’en-tête le confirme. Vous pouvez diviser la fenêtre et garder watch d’un côté et journalctl -f de l’autre. C’est tout l’intérêt de un terminal de travail basé sur tmux. Lorsque la même question concerne plusieurs serveurs à la fois, utilisez plutôt un outil conçu pour administrer plusieurs serveurs Linux qu’un écran rempli de fenêtres watch.

Les écrans présentés ici sont fournis à titre d’exemple. La disposition des colonnes et les chaînes de version varient selon les distributions et les versions de procps-ng. Exécutez donc man watch sur votre propre machine pour connaître les options réellement disponibles dans votre build.

FAQ

Pourquoi watch ignore-t-il le pipe dans watch mycmd | grep foo ?

Votre shell découpe la ligne au niveau du pipe avant même le démarrage de watch. Il envoie donc l’affichage de watch lui-même vers grep, et la sortie de la commande n’est jamais filtrée. Entourez plutôt tout le pipeline de guillemets : watch 'mycmd | grep foo'. watch transmet cet argument unique à sh -c, qui exécute le pipeline à chaque cycle. La même règle s’applique aux globs et à la substitution de commande.

Quel intervalle dois-je utiliser avec watch ?

Adaptez-le à la vitesse d’évolution de la valeur et au coût d’une exécution. Une demi-seconde convient aux compteurs rapides, et 0.1 seconde est l’intervalle minimal accepté par watch. Trente à soixante secondes conviennent aux disques et aux certificats. La durée d’exécution de la commande s’ajoute à l’intervalle, sauf si vous passez -p. Une commande lente utilisée avec -n 1 s’exécute alors en continu, sans pause.

watch peut-il suivre un fichier journal ?

Non. watch redessine une trame et ne conserve aucun historique. Toute ligne qui apparaît puis disparaît entre deux cycles est définitivement perdue. journalctl -fu <unit> et tail -f diffusent les nouvelles lignes au fur et à mesure de leur arrivée, ce qui convient aux journaux. Utilisez watch pour les valeurs qui représentent un état courant, comme le pourcentage d’utilisation d’un disque ou la longueur d’une file d’attente.

Comment faire arrêter watch lorsque l’événement attendu se produit ?

Utilisez -g (--chgexit) et fournissez-lui une commande dont la sortie reste identique jusqu’à cet événement. Une sortie contenant une horloge ou un PID change dès la première actualisation et provoque un arrêt immédiat. systemctl is-active myapp fonctionne donc dans ce cas, contrairement à systemctl status myapp. Pour une condition réelle, comme un compteur qui atteint zéro, utilisez une boucle shell until, car watch peut seulement détecter que la sortie a changé.

Pourquoi watch indique-t-il que la commande est introuvable alors qu’elle fonctionne dans mon shell ?

watch transmet la commande à sh -c. Ce shell ne lit pas .bashrc, donc vos alias et vos fonctions shell n’y existent pas. Le message est généralement sh: 1: ll: not found. Écrivez la commande complète ou utilisez le chemin absolu d’un binaire présent uniquement dans votre PATH interactif.