Linux sans magie #16 — Processus et PID : comprendre ce qui tourne et arrêter proprement un programme

Comprendre les processus Linux, les PID, ps, pgrep et les signaux avec un lab simple pour identifier puis arrêter proprement un programme.

Quand vous lancez une commande sous Linux, vous ne manipulez pas seulement un fichier exécutable : vous créez un processus, c’est-à-dire une instance en cours d’exécution à laquelle le système attribue notamment un identifiant, le PID.

Comprendre cette différence est une étape importante pour administrer Linux proprement. Elle permet de répondre à des questions très concrètes : qu’est-ce qui tourne ? quel processus correspond à mon programme ? comment retrouver son PID ? et surtout, comment lui demander de s’arrêter sans utiliser immédiatement kill -9 ?

L’objectif de cet article est de construire ce raisonnement avec un lab volontairement simple et réversible.

Contexte et problème

Jusqu’ici, la série a surtout traité les fichiers, les permissions et les privilèges. Avec les processus, nous passons à ce qui se produit pendant l’exécution.

Un même programme peut être lancé plusieurs fois. Chaque exécution peut alors avoir son propre PID, son propre état et son propre contexte d’exécution.

Par exemple, le fichier /usr/bin/sleep peut servir à lancer plusieurs processus distincts :

/usr/bin/sleep 300   → processus A → PID 4120
/usr/bin/sleep 600   → processus B → PID 4187

Les PID ci-dessus sont uniquement illustratifs. Les valeurs réelles sont attribuées par le système et changent d’une exécution à l’autre.

Cette distinction est essentielle : pour observer ou envoyer un signal, Linux cible un processus en cours d’exécution, pas simplement le nom du fichier présent sur le disque.

Concept ou architecture

Programme et processus ne sont pas la même chose

Un programme est un ensemble d’instructions stocké sur disque. Un processus est une instance de ce programme en cours d’exécution.

On peut donc avoir :

programme
   │
   ├── processus 1 → PID 5012
   ├── processus 2 → PID 5089
   └── processus 3 → PID 5154

Le PID, pour Process ID, sert à identifier un processus.

L’outil ps affiche des informations sur une sélection de processus actifs. Selon ses options, il peut notamment montrer le PID, le terminal associé, le temps CPU cumulé et le nom de la commande.

Pour rechercher un processus par son nom, pgrep est souvent plus direct : il parcourt les processus et retourne les PID correspondant aux critères indiqués.

kill envoie un signal

Le nom kill prête facilement à confusion. La commande n’implique pas forcément une destruction brutale du processus. Elle envoie un signal.

Dans les environnements utilisés pour ce lab, kill <PID> demande par défaut un arrêt avec SIGTERM. Pour rendre l’intention explicite et éviter toute ambiguïté liée à l’implémentation de kill fournie par le shell ou par le système, nous utiliserons aussi la forme kill -TERM <PID>.

SIGTERM signifie en pratique :

« termine-toi proprement »

Un programme peut installer un gestionnaire pour ce signal et effectuer du nettoyage avant de se terminer.

À l’inverse, SIGKILL ne peut pas être intercepté, bloqué ou ignoré. Le processus ne peut donc pas exécuter son propre traitement de sortie après réception de ce signal.

C’est pourquoi SIGTERM doit rester le premier réflexe dans un arrêt normal.

Prérequis

Le lab nécessite seulement :

  • une machine Linux ou une VM de test ;
  • un shell interactif ;
  • les commandes sleep, ps, pgrep et kill ;
  • aucun droit root pour le scénario principal.

Vérifiez la présence des outils :

command -v sleep
command -v ps
command -v pgrep
command -v kill

Le lab n’altère aucun service système et ne modifie aucun fichier de configuration.

Mise en pratique

1. Lancer un processus de laboratoire

Dans votre terminal, exécutez :

sleep 600 &

La commande sleep 600 attend pendant 600 secondes. Le caractère & demande au shell de lancer la commande en arrière-plan afin de vous rendre immédiatement la main.

Selon le shell, une ligne proche de celle-ci peut apparaître :

[1] 12345

Le nombre 12345 est un exemple de PID. Ne réutilisez pas cette valeur : utilisez toujours celle réellement observée sur votre machine.

2. Observer le processus avec ps

Commencez par :

ps

Par défaut, ps affiche généralement une sélection limitée de processus liés à l’utilisateur et au terminal courants. Vous devriez notamment retrouver votre shell et le processus sleep lancé juste avant.

Pour afficher explicitement le PID et la commande du processus recherché, vous pouvez utiliser :

ps -o pid,comm,args -C sleep

Sur une distribution utilisant procps-ng, cette forme permet d’afficher les processus dont le nom de commande correspond à sleep.

Si votre système utilise une autre implémentation de ps ou ne prend pas en charge -C, utilisez simplement la méthode suivante avec pgrep.

3. Rechercher le PID avec pgrep

Exécutez :

pgrep -a sleep

L’option -a demande d’afficher les PID trouvés avec la ligne de commande correspondante.

Vous pouvez obtenir quelque chose comme :

12345 sleep 600

Encore une fois, le PID réel sera différent.

Si plusieurs processus sleep existent déjà, ne choisissez pas un PID au hasard. Identifiez celui dont les arguments correspondent à votre lab.

Une alternative encore plus sûre consiste à relancer le lab dans un terminal propre et à noter immédiatement le PID affiché par le shell.

4. Envoyer un arrêt normal

Une fois le PID identifié, demandez d’abord un arrêt normal :

kill <PID>

Remplacez <PID> par la valeur réellement observée.

Pour rendre le signal explicite, vous pouvez utiliser :

kill -TERM <PID>

Pour ce lab, les deux formes conduisent au même objectif : demander au processus sleep de se terminer avec SIGTERM.

Résultat attendu

Après réception de SIGTERM, le processus sleep doit disparaître.

Le shell peut également afficher un message indiquant que le job d’arrière-plan est terminé.

5. Vérifier que le processus n’existe plus

Utilisez :

ps -p <PID>

Si le processus n’existe plus, ps ne doit plus afficher de ligne de processus correspondant à ce PID.

Vous pouvez également vérifier avec :

pgrep -a sleep

Attention : cette seconde commande peut encore afficher d’autres processus sleep sans rapport avec votre lab. La vérification par PID reste donc la plus précise.

Vérification

Le lab est réussi lorsque vous observez cette séquence :

sleep absent ou non ciblé
    ↓
sleep 600 &
    ↓
PID identifié
    ↓
kill <PID>  → SIGTERM
    ↓
ps -p <PID> → processus absent

Le résultat important n’est pas seulement « le programme s’est arrêté ». Le lecteur doit pouvoir démontrer qu’il a :

  1. identifié le bon processus ;
  2. utilisé son PID ;
  3. envoyé un signal d’arrêt normal ;
  4. vérifié la disparition du processus ciblé.

Bonnes pratiques

Commencez toujours par identifier précisément le processus avant d’envoyer un signal.

Évitez de travailler uniquement avec un nom générique lorsqu’il peut correspondre à plusieurs instances. Un PID permet de cibler une instance déterminée, même si plusieurs processus exécutent le même programme.

Préférez également :

kill <PID>

ou :

kill -TERM <PID>

avant d’envisager un signal plus brutal.

Après l’envoi du signal, vérifiez le résultat avec une commande observable comme :

ps -p <PID>

Ne considérez pas l’absence de message d’erreur comme une preuve suffisante que le processus s’est effectivement terminé.

Sécurité

Sous Linux, un utilisateur non privilégié ne peut pas envoyer arbitrairement des signaux à n’importe quel processus.

Les règles exactes dépendent notamment des identités utilisateur du processus émetteur et du processus cible. Un processus disposant de la capability CAP_KILL peut contourner certains contrôles de permission de signalisation.

Pour ce lab, cette complexité est volontairement évitée : le processus sleep est lancé et arrêté par le même utilisateur.

N’ajoutez donc pas sudo devant kill simplement parce qu’un signal est refusé. Un refus peut être un indice que vous ciblez un processus qui ne vous appartient pas ou que le contexte de sécurité mérite d’être compris avant toute élévation de privilège.

Pourquoi ne pas commencer par kill -9 ?

La commande :

kill -9 <PID>

envoie SIGKILL.

Ce signal peut être nécessaire dans certains cas extrêmes, mais ce n’est pas une méthode normale d’arrêt. SIGKILL ne peut pas être intercepté par le processus : celui-ci ne peut donc pas exécuter un gestionnaire de signal pour terminer proprement son travail.

Le bon raisonnement est plutôt :

identifier
→ SIGTERM
→ vérifier
→ diagnostiquer si le processus reste présent
→ SIGKILL seulement si le contexte le justifie

Coûts

Ce lab ne nécessite aucun service payant.

Il peut être exécuté sur une VM Linux existante, une machine physique ou un environnement de laboratoire déjà disponible. Aucun coût logiciel spécifique n’est associé aux commandes utilisées.

Limites et points de vigilance

Cet article introduit volontairement le modèle de base. Il ne traite pas encore :

  • des threads ;
  • des processus zombies ;
  • de /proc en profondeur ;
  • des cgroups ;
  • de nice et renice ;
  • des services systemd ;
  • du job control avec jobs, fg et bg ;
  • des outils interactifs comme top ou htop.

Ces sujets appartiennent aux étapes suivantes du bloc consacré aux processus et services.

Les options disponibles peuvent aussi varier entre implémentations de commandes Unix. Les exemples ps décrits ici correspondent à procps-ng, très courant sur les distributions Linux généralistes.

Enfin, un PID est une valeur attribuée dynamiquement. Ne copiez jamais un PID provenant d’un exemple ou d’une ancienne session pour envoyer un signal sur votre propre système.

Rollback ou nettoyage

Aucun rollback de configuration n’est nécessaire : le lab ne modifie pas le système de façon persistante.

Si le processus sleep existe encore à la fin du lab, identifiez-le précisément :

pgrep -a sleep

puis envoyez SIGTERM au PID correspondant au sleep 600 créé pour l’exercice :

kill -TERM <PID>

Vérifiez ensuite :

ps -p <PID>

Lorsque le PID n’apparaît plus, le nettoyage est terminé.

Références officielles

Conclusion

Un processus est une instance en cours d’exécution, identifiable notamment par un PID. Cette idée simple devient rapidement centrale pour comprendre Linux : observer ce qui tourne, cibler la bonne instance et intervenir proprement.

Le réflexe à retenir est donc : identifier avant d’agir, envoyer SIGTERM avant SIGKILL, puis vérifier le résultat.

Dans l’article suivant, nous pourrons nous appuyer sur cette base pour comprendre ce qui a changé entre la gestion historique des services System V et le modèle systemd moderne.