Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Jobs et contrôle des tâches dans le shell

Par mis à jour le

Améliorer cette page

Une tâche qui bloque votre terminal n'est pas une fatalité. Ctrl+Z la suspend, bg la relance en arrière-plan, fg la ramène devant vous. Le contrôle des tâches (job control) est le mécanisme natif du shell pour jongler entre plusieurs processus sans ouvrir de nouveau terminal. Les comportements décrits ici ont été vérifiés avec Bash 5.2 sur Debian 13, Ubuntu 24.04 et AlmaLinux 10, dans un pseudo-terminal.

  • Suspendre une tâche en cours avec Ctrl+Z
  • Lister les tâches actives avec jobs -l
  • Passer une tâche en arrière-plan avec bg
  • Ramener une tâche au premier plan avec fg
  • Référencer une tâche par son numéro avec %n
  • Tuer une tâche avec kill %n
  • Détacher définitivement une tâche avec disown

Cette compétence sert dès qu'une commande prend du temps et bloque votre prompt. Une tâche (job) est une commande lancée depuis votre shell, suivie par lui tant que la session dure :

  • une compilation ou une copie longue,
  • un éditeur ouvert que vous voulez mettre de côté,
  • un processus que vous avez lancé en foreground par erreur,
  • une tâche que vous voulez survivre à la fermeture du terminal.

L'opérateur & place le processus en background (arrière-plan) dès le lancement. Le shell affiche le numéro de job et le PID, puis rend le prompt immédiatement :

Fenêtre de terminal
sleep 60 &
[1] 1842

[1] est le numéro de tâche (job number), local à votre shell : c'est lui qu'attendent fg, bg et kill %1. 1842 est le PID, l'identifiant du processus pour tout le système. La variable spéciale $! contient le PID de la dernière tâche lancée en arrière-plan : capturez-la aussitôt, le prochain & l'écrasera.

Fenêtre de terminal
# Capturer le PID de la dernière tâche lancée en background
sleep 60 &
MYPID=$!
echo "PID de la tâche : $MYPID"

jobs liste les tâches de la session courante seulement, avec leur numéro et leur état ; l'option -l ajoute le PID. Dans l'exemple ci-dessous, sleep 60 tourne en arrière-plan et vim a été suspendu :

Fenêtre de terminal
jobs -l
[1]- 2075842 Running sleep 60 &
[2]+ 2075843 Stopped vim fichier.txt

La tâche courante (+) est celle que fg et bg visent sans argument : la dernière suspendue ou lancée en arrière-plan, et Bash donne la priorité à une tâche suspendue. Mesuré avec Bash 5.2 : un sleep 200 suspendu reste marqué + même quand un sleep 201 & est lancé après lui. Colonnes :

ÉlémentSignification
[1]Numéro de tâche
+Tâche courante (celle que fg reprend par défaut)
-Tâche précédente
Running / StoppedÉtat
sleep 60 &Commande

Pendant qu'une commande tourne au premier plan (foreground), Ctrl+Z lui envoie le signal de suspension SIGTSTP et rend le prompt :

vim fichier.txt
^Z
[1]+ Stopped vim fichier.txt

Le processus est suspendu (état T dans ps) : il n'utilise plus le CPU mais reste en mémoire, prêt à reprendre exactement où il s'était arrêté. C'est ce qui rend Ctrl+Z pratique pour mettre un éditeur de côté le temps de lancer une commande.

bg (background) fait reprendre une tâche suspendue en arrière-plan : elle continue son travail, et vous gardez le prompt. C'est le rattrapage d'une commande longue lancée sans & par erreur, sans perdre ce qui a déjà été fait.

Fenêtre de terminal
bg %1

La tâche suspendue [1] reprend son exécution en arrière-plan. Sans argument, bg reprend la tâche courante (marquée +) :

Fenêtre de terminal
# Suspendre puis reprendre en background
sleep 60
^Z
bg

Une limite, mesurée avec cat & : un programme qui lit le terminal ne peut pas tourner en arrière-plan. Il reçoit le signal SIGTTIN et s'arrête de nouveau, et jobs l'affiche alors en Stopped (tty input).

fg (foreground) redonne le premier plan à une tâche : votre terminal est à nouveau bloqué tant qu'elle n'est pas terminée, mais vous retrouvez son interactivité, indispensable pour un éditeur mis de côté.

Fenêtre de terminal
fg %1
Fenêtre de terminal
fg # reprend la tâche courante (+)
fg %2 # reprend la tâche numéro 2

Une tâche qui n'existe plus répond fg: %2: no such job : elle s'est terminée entre-temps, ou le numéro est faux.

En plus de %n, vous pouvez désigner une tâche par le début de sa commande, ce qui évite de consulter jobs avant chaque action. La référence doit rester non ambiguë : si deux tâches commencent par le même mot, Bash refuse d'en choisir une.

Fenêtre de terminal
fg %vim # reprend la tâche dont la commande commence par "vim"
kill %sleep # tue la tâche dont la commande commence par "sleep"

kill accepte un numéro de job précédé de % aussi bien qu'un PID. Sans option, il envoie SIGTERM, la demande d'arrêt propre ; -9 envoie SIGKILL, que le programme ne peut pas intercepter.

Fenêtre de terminal
kill %1 # envoie SIGTERM à la tâche 1
kill -9 %2 # envoie SIGKILL à la tâche 2

Pour nettoyer toutes les tâches de la session d'un coup, jobs -p fournit uniquement leurs PID, que kill reçoit en une seule ligne :

Fenêtre de terminal
kill $(jobs -p)

wait bloque le shell jusqu'à la fin du processus désigné, puis place son code de sortie dans $?. C'est la brique de synchronisation des scripts qui lancent plusieurs traitements en parallèle.

Fenêtre de terminal
sleep 3 &
MYPID=$!
echo "En attente..."
wait $MYPID
echo "Terminé avec le code : $?"

Sans argument, wait attend toutes les tâches background actives du shell.

disown retire une tâche de la table des jobs : le shell ne lui relaiera plus le SIGHUP qu'il reçoit à la déconnexion, et elle survit donc à la fermeture de la session. Il accepte un numéro de job (%1) comme un PID (vérifié).

Fenêtre de terminal
sleep 120 &
MYPID=$!
disown $MYPID
jobs # la tâche n'apparaît plus
ps -p $MYPID # mais le processus est toujours en vie

Un simple exit ne tue d'ailleurs pas une tâche en cours d'exécution en arrière-plan : l'option huponexit de Bash est désactivée par défaut (vérifié avec shopt huponexit). Le danger vient du SIGHUP que le shell reçoit quand la connexion SSH ou le terminal se ferment : il le relaie alors à ses tâches, et mesuré sur Debian 13 et AlmaLinux 10, un sleep lancé avec & meurt avec lui.

Deux variantes couvrent les autres besoins : -h protège la tâche sans la retirer de la table, ce qui laisse fg possible, et -a traite toutes les tâches d'un coup.

Fenêtre de terminal
disown -h $! # protège la tâche du SIGHUP sans la retirer de jobs
disown -a # détache toutes les tâches

Ce tableau rassemble les gestes de la page dans l'ordre où ils servent : le lancement, la suspension, la reprise, puis le détachement. Gardez-le sous la main lors de vos premières sessions.

ActionRaccourci / Commande
Suspendre (foreground → stopped)Ctrl+Z
Reprendre en arrière-planbg %n
Ramener au premier planfg %n
Lancer directement en backgroundcommande &
Capturer le PID de la dernière tâche background$!
Lister les tâchesjobs -l
Tuer par numéro de jobkill %n
Attendre la finwait $PID
Détacher du shelldisown $PID

Les symptômes ci-dessous viennent presque tous d'une confusion entre les trois états d'une tâche (premier plan, arrière-plan, suspendue) ou entre numéro de job et PID. Commencez toujours par jobs -l, qui montre les deux.

SymptômeCause probableSolution
Après bg, la tâche repasse en Stopped (tty input)Le programme lit le terminal : en arrière-plan, il reçoit SIGTTIN et s'arrête (mesuré avec cat &)La ramener avec fg, ou la relancer avec une entrée redirigée (< /dev/null)
fg %2 répond fg: %2: no such jobLa tâche est terminée, ou le numéro est fauxVérifier avec jobs -l et utiliser le bon numéro
La tâche disparaît à la déconnexion malgré &SIGHUP relayé par le shell à la fermeture de sessionUtiliser disown -h ou nohup
kill %1 ne termine pas la tâcheProcessus en état D ou ignore SIGTERMkill -9 %1 ; si état D, diagnostiquer l'I/O bloqué
$! vide dans le scriptAucune commande n'a encore été lancée avec &Ajouter & à la fin de la commande
  • & place un processus en arrière-plan au lancement ; Ctrl+Z suspend un processus en cours.
  • jobs -l liste les tâches avec leur numéro et leur PID ; + marque la tâche courante, de préférence une tâche suspendue.
  • bg %n reprend, fg %n ramène, kill %n tue, toujours par numéro de job.
  • $! contient le PID de la dernière tâche lancée en arrière-plan.
  • Un exit ne tue pas les tâches qui tournent ; le SIGHUP de la déconnexion, si.
  • disown détache une tâche déjà lancée pour qu'elle survive à la fermeture de la session.

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn