Linux sans magie #20 — Premier plan, arrière-plan et jobs : comprendre &, jobs, fg et bg
Comprendre le job control dans Bash : lancer une commande en arrière-plan, lister les jobs, suspendre un programme et le reprendre avec fg ou bg.
Dans les articles précédents, nous avons vu comment identifier des processus, gérer des services avec systemctl et lire leurs logs avec journalctl. Il reste pourtant un comportement très quotidien du terminal qui peut sembler étrange au début : une commande peut occuper le terminal, être envoyée en arrière-plan, être suspendue, puis revenir au premier plan.
Bash appelle cela le job control.
L’objectif de cet article est de comprendre ce que représentent les jobs du shell et d’utiliser correctement &, jobs, fg, bg et Ctrl+Z, sans les confondre avec une liste générale des processus du système.
Contexte et problème
Lancez par exemple :
sleep 300
Le terminal semble alors « bloqué ». En réalité, il ne l’est pas : Bash attend simplement la fin du programme placé au premier plan.
Pendant ce temps, vous ne retrouvez pas l’invite du shell pour saisir une autre commande dans ce même terminal.
Il existe plusieurs façons de gérer cette situation. On peut notamment :
- démarrer directement une commande en arrière-plan ;
- suspendre une commande qui tourne au premier plan ;
- reprendre un job suspendu en arrière-plan ;
- ramener un job au premier plan ;
- afficher les jobs que le shell courant connaît.
Ces opérations relèvent du shell. Elles ne remplacent ni ps, ni les outils de supervision des processus.
Concept ou architecture
Processus et job ne désignent pas exactement la même chose
Un processus est une entité gérée par le noyau Linux et possède notamment un PID.
Un job, dans Bash, est une construction du shell utilisée pour suivre une commande ou un pipeline lancé depuis ce shell lorsque le job control est actif.
Le shell attribue à ses jobs des identifiants comme :
[1]
[2]
Dans les commandes de job control, on référence généralement ces jobs avec une notation appelée jobspec :
%1
%2
Ce numéro de job n’est pas un PID.
La commande :
jobs -l
permet justement d’afficher les jobs en incluant des PID, ce qui aide à voir la différence entre les deux notions.
Premier plan
Une commande au premier plan contrôle le terminal pendant son exécution. Bash attend sa fin ou un changement d’état avant de rendre l’invite.
Exemple :
sleep 300
Tant que sleep reste au premier plan, le shell n’affiche pas de nouvelle invite dans ce terminal.
Arrière-plan avec &
Pour demander à Bash de lancer une commande en arrière-plan, on ajoute & à la fin :
sleep 300 &
Bash rend alors immédiatement la main et affiche généralement un numéro de job ainsi qu’un identifiant de processus.
Le programme continue à s’exécuter, mais l’invite du shell redevient disponible.
Cela ne signifie pas que la commande est devenue un service, ni qu’elle est indépendante du shell ou de la session. & signifie seulement qu’elle est lancée en arrière-plan dans le contexte du job control du shell.
jobs : voir les jobs du shell courant
La commande :
jobs
affiche les jobs actifs connus du Bash courant.
Exemple de présentation possible :
[1]+ Running sleep 300 &
Le rendu exact dépend de l’état du job et de la version du shell.
Pour afficher aussi les PID :
jobs -l
Le point important est la portée de la commande : jobs ne parcourt pas tous les processus de la machine.
Si vous ouvrez un second terminal et exécutez jobs, il ne retrouvera normalement pas les jobs créés dans le premier Bash. Chaque shell maintient sa propre table de jobs.
Pour rechercher des processus au niveau du système, utilisez plutôt des commandes comme :
ps
ou les méthodes vues dans l’article consacré aux processus et PID.
Suspendre avec Ctrl+Z
Supposons qu’une commande tourne déjà au premier plan :
sleep 300
Vous pouvez utiliser :
Ctrl+Z
Le terminal envoie alors l’action de suspension via le mécanisme de contrôle du terminal, et Bash reprend la main lorsque le job est arrêté.
Vous pouvez ensuite vérifier son état :
jobs
Vous verrez un état du type :
[1]+ Stopped sleep 300
Le programme n’est pas terminé : il est suspendu.
Il faut distinguer cette action de Ctrl+C. Dans un terminal interactif standard, Ctrl+C provoque normalement l’envoi de SIGINT au job au premier plan afin de demander son interruption. Ctrl+Z, lui, provoque normalement une suspension avec le mécanisme associé à SIGTSTP.
Autrement dit :
Ctrl+C → demander l'interruption
Ctrl+Z → suspendre le job
Reprendre un job avec bg
Un job suspendu peut être repris en arrière-plan avec :
bg %1
Ici %1 désigne le job numéro 1 dans la table de jobs du shell.
Après cette commande, vérifiez :
jobs
Le job doit apparaître comme actif, généralement avec un état Running.
Si aucun jobspec n’est fourni, Bash peut utiliser son notion de job courant. Pour rester explicite dans un lab ou une procédure, utiliser %1, %2, etc. évite les ambiguïtés lorsque plusieurs jobs existent.
Ramener un job au premier plan avec fg
Pour reprendre le job 1 au premier plan :
fg %1
Le job reprend alors le contrôle du terminal et Bash attend de nouveau sa fin ou un changement d’état.
Si vous exécutez ensuite Ctrl+C, vous pouvez interrompre le sleep du lab et récupérer l’invite.
La commande fg sert donc à faire revenir dans le terminal actif un job qui était suspendu ou exécuté en arrière-plan.
Comprendre %1, %2, %+ et %-
Bash appelle jobspec la notation utilisée pour désigner un job.
Les formes les plus utiles pour commencer sont :
%1 → job numéro 1
%2 → job numéro 2
%+ → job courant
%- → job précédent
Dans la sortie de jobs, le job courant est généralement marqué par + et le précédent par -.
Pour une première utilisation, les numéros explicites %1 et %2 sont souvent plus simples à suivre.
Prérequis
Le lab nécessite :
- une session Bash interactive ;
- le job control actif ;
- la commande
sleep, présente sur les environnements Linux courants.
Vérifiez le shell courant :
echo "$BASH_VERSION"
Puis vérifiez que sleep est disponible :
command -v sleep
Dans un script Bash non interactif, le comportement du job control n’est pas le même et il peut être désactivé. Cet article traite volontairement le cas du terminal interactif.
Mise en pratique
1. Lancer une commande directement en arrière-plan
Exécutez :
sleep 300 &
Bash doit rendre immédiatement l’invite.
Affichez la table des jobs :
jobs
Puis :
jobs -l
Résultat attendu
Vous devez voir au moins un job en cours d’exécution. Avec jobs -l, un PID doit également apparaître.
Retenez les deux identifiants :
numéro de job → utilisé par fg/bg avec %N
PID → identifiant du processus au niveau système
2. Ramener le job au premier plan
Si le job est numéro 1 :
fg %1
Le prompt disparaît tant que sleep reste au premier plan.
3. Suspendre le job
Appuyez sur :
Ctrl+Z
Puis :
jobs
Le job doit apparaître comme suspendu ou Stopped.
4. Le reprendre en arrière-plan
Exécutez :
bg %1
Puis vérifiez :
jobs
Le job doit de nouveau apparaître en cours d’exécution.
5. Le ramener une dernière fois au premier plan
fg %1
Terminez le lab avec :
Ctrl+C
Puis vérifiez :
jobs
Une fois que Bash a pris en compte la fin du job, il ne doit plus apparaître dans la table des jobs actifs.
Vérification
Le lab est réussi si vous êtes capable de décrire cette séquence :
sleep 300 &
↓
job lancé en arrière-plan
↓
fg %1
↓
job au premier plan
↓
Ctrl+Z
↓
job suspendu
↓
bg %1
↓
job repris en arrière-plan
↓
fg %1 puis Ctrl+C
↓
job interrompu et lab terminé
Bonnes pratiques
Utilisez jobs avant fg ou bg lorsque plusieurs jobs existent :
jobs -l
Cela évite de manipuler le mauvais job.
Préférez des jobspecs explicites dans une procédure :
fg %2
bg %1
Ne supposez pas qu’un numéro de job reste valable longtemps. Lorsque des jobs se terminent et que la table évolue, les numéros disponibles peuvent changer lors de sessions ultérieures.
Enfin, ne transformez pas & en solution universelle pour faire tourner une application durablement. Pour un service système ou une application qui doit être supervisée, redémarrée et gérée au boot, un gestionnaire de services comme systemd est généralement plus approprié.
Sécurité
Le job control ne donne aucun privilège supplémentaire. Une commande lancée avec &, fg ou bg conserve les droits du processus et de l’utilisateur qui l’a lancée.
Le risque principal est opérationnel : envoyer en arrière-plan une commande ayant des effets importants ne réduit pas ces effets. Une suppression, une copie massive, une opération réseau ou une modification de configuration reste potentiellement dangereuse, qu’elle soit visible au premier plan ou non.
Dans un environnement sensible, vérifiez toujours la commande avant de la lancer en arrière-plan et contrôlez son état au lieu de considérer qu’un retour immédiat du prompt signifie que l’opération est terminée.
Coûts
Le lab n’utilise aucune ressource payante particulière. Il s’exécute avec des commandes locales très légères.
Sur une machine facturée à l’usage, une commande réelle exécutée longtemps en arrière-plan peut évidemment continuer à consommer CPU, mémoire, stockage ou trafic réseau. Le caractère « arrière-plan » ne supprime pas le coût de la charge de travail.
Limites et points de vigilance
Cet article couvre le job control interactif de Bash. Il ne traite pas en profondeur :
nohup;disown;- la survie d’un processus après fermeture du terminal ;
- les sessions et groupes de processus en détail ;
- le controlling terminal ;
- les multiplexeurs de terminal comme
tmuxouscreen; - les différences de job control entre shells.
Le comportement décrit suppose également que le job control est actif. Dans des contextes non interactifs ou des scripts, les hypothèses de cet article ne doivent pas être transposées automatiquement.
Enfin, un programme peut traiter ou ignorer certains signaux selon sa propre logique. Les raccourcis clavier décrits ici correspondent au comportement habituel d’un terminal interactif, mais ils ne constituent pas une garantie que toute application réagira de la même façon.
Rollback ou nettoyage
Le lab ne crée aucun fichier ni service permanent.
Si un sleep reste actif dans la table de jobs, ramenez-le au premier plan :
fg %1
puis utilisez :
Ctrl+C
Si plusieurs jobs existent, commencez par :
jobs -l
et identifiez précisément celui du lab avant d’agir.
Références officielles
- Bash Reference Manual — Job Control — GNU Project
- Bash Reference Manual — Job Control Builtins — GNU Project
Conclusion
Le job control devient beaucoup plus simple dès que l’on sépare deux niveaux : Linux gère les processus et leurs PID, tandis que Bash maintient une table de jobs pour les commandes lancées depuis le shell interactif.
& lance en arrière-plan, jobs montre ce que le shell suit, Ctrl+Z suspend, bg reprend en arrière-plan et fg ramène au premier plan.
Ce mécanisme est utile pour piloter ponctuellement des commandes dans un terminal. Il ne remplace ni la gestion des processus à l’échelle du système, ni un véritable gestionnaire de services.
