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

Lancer une commande en arrière-plan sous Linux

Par mis à jour le

Améliorer cette page

Ajouter & à la fin d'une commande suffit pour la lancer en arrière-plan. Le shell rend le prompt immédiatement et le processus continue de tourner. Associé à une redirection et à disown, c'est la base pour lancer des tâches longues sans bloquer votre session, et pour qu'elles survivent à une déconnexion SSH. Les comportements décrits ici ont été vérifiés avec Bash 5.2 sur Debian 13, Ubuntu 24.04 et AlmaLinux 10.

  • Lancer n'importe quelle commande en background avec &
  • Récupérer le PID de la tâche avec $!
  • Rediriger correctement stdout et stderr d'un processus background
  • Attendre la fin d'une ou plusieurs tâches avec wait
  • Détacher une tâche du shell avec disown pour qu'elle survive à la fermeture

L'arrière-plan sert dès qu'une commande dure plus longtemps que votre patience, ou que plusieurs traitements indépendants peuvent tourner en même temps. Trois situations reviennent sans cesse sur un serveur :

  • Vous lancez une sauvegarde, une compilation ou un téléchargement et vous voulez continuer à utiliser le terminal.
  • Vous voulez paralléliser plusieurs opérations dans un script.
  • Vous avez lancé une commande en foreground et vous voulez la rendre indépendante de votre session SSH.

L'opérateur & en fin de ligne lance la commande en background : le shell n'attend pas qu'elle se termine et rend la main aussitôt.

Fenêtre de terminal
sleep 60 &

Le shell affiche immédiatement :

[1] 1842
  • [1] : numéro de job (utilisé par jobs, fg, bg)
  • 1842 : PID du processus

Le prompt est restitué et la commande tourne en parallèle. Pour le vérifier, interrogez le processus par son PID avec ps -p : l'état S (en attente) ou R (en cours) confirme qu'il est vivant, une sortie vide qu'il est terminé.

Fenêtre de terminal
# Vérifier qu'elle tourne bien
ps -p 1842 -o pid,stat,comm
PID STAT COMMAND
1842 S sleep

La variable spéciale $! contient le PID de la dernière commande lancée en background. Capturez-la immédiatement dans une variable à vous : le prochain & écrase sa valeur, et vous perdriez toute référence à la tâche précédente.

Fenêtre de terminal
sleep 30 &
MYPID=$!
echo "La tâche tourne avec le PID : $MYPID"

Un processus en arrière-plan reste rattaché au terminal pour ses sorties. Sans redirection, stdout et stderr s'y affichent de manière asynchrone, au milieu de ce que vous tapez : rien n'est perdu, mais tout se mélange. Redirigez donc toujours les processus background qui produisent de la sortie :

Fenêtre de terminal
ma-commande-longue > sortie.log 2>&1 &
MYPID=$!
  • > sortie.log : redirige stdout vers le fichier
  • 2>&1 : redirige stderr vers le même fichier
  • & : place en background

L'ordre compte : > sortie.log doit précéder 2>&1. Pour ajouter à un fichier de log existant plutôt que l'écraser, utilisez >> :

Fenêtre de terminal
ma-commande >> /var/log/mon-script.log 2>&1 &

wait bloque le shell jusqu'à la fin du processus indiqué, puis place son code de sortie dans $? : 0 pour un succès, autre chose pour un échec. Lisez $? juste après, la moindre commande intermédiaire l'écrase.

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

wait accepte plusieurs PID et ne rend la main que lorsque tous sont terminés. C'est le point de synchronisation d'un script qui lance plusieurs traitements indépendants, bien plus fiable qu'un sleep arbitraire, trop court ou trop long selon les jours.

Fenêtre de terminal
# Lancer 3 opérations en parallèle
tache_a &
A=$!
tache_b &
B=$!
tache_c &
C=$!
# Attendre toutes les 3 avant de continuer
wait $A $B $C
echo "Toutes terminées"

Quand votre shell reçoit SIGHUP, parce que la connexion SSH ou le terminal se ferment, il le relaie à toutes ses tâches avant de quitter (man bash), ce qui les tue. Mesuré sur Debian 13 et AlmaLinux 10 : un sleep lancé avec & meurt quand le shell reçoit SIGHUP, mais survit à un simple exit, l'option huponexit étant désactivée par défaut.

disown retire une tâche de la liste des jobs du shell, qui ne lui relaie donc plus ce SIGHUP. Il accepte aussi bien un PID qu'un numéro de job :

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

Les trois formes diffèrent par ce qu'elles laissent dans la table des jobs : garder la tâche visible permet encore de la ramener avec fg, la retirer la rend indépendante pour de bon.

OptionEffet
disown $PIDRetire la tâche de jobs : le shell ne lui relaie plus SIGHUP
disown -h $PIDMême protection, sans la retirer de jobs
disown -aDétache toutes les tâches

disown -h est utile si vous voulez encore pouvoir utiliser fg ou jobs sur la tâche.

Le pattern complet pour une tâche longue résistante à la déconnexion réunit les trois briques de la page : la redirection fournit un log consultable, le & libère le prompt, et disown protège la tâche du SIGHUP de fin de session.

Fenêtre de terminal
commande > sortie.log 2>&1 &
disown $!

Ou en version plus lisible dans un script :

Fenêtre de terminal
ma-commande > /var/log/ma-commande.log 2>&1 &
PID=$!
disown $PID
echo "Tâche lancée, PID=$PID, sortie dans /var/log/ma-commande.log"

La plupart des surprises viennent de ce que & ne fait qu'une chose : libérer le prompt. Il ne redirige pas la sortie, ne protège pas du SIGHUP et ne baisse pas la priorité ; chaque ligne du tableau ajoute la brique qui manquait.

SymptômeCause probableSolution
La sortie du background s'affiche en plein milieu de votre promptPas de redirectionAjouter > sortie.log 2>&1 &
$! videAucune commande n'a encore été lancée avec &Vérifier que la commande se termine par &
La tâche meurt à la déconnexion malgré &SIGHUP relayé par le shell à la fermeture de sessionAjouter disown $PID après le lancement
wait $PID retourne immédiatementLe processus est déjà terminéNormal, vérifier son code retour avec echo $?
La tâche consomme 100% CPU en backgroundAucun throttling impliciteLancer avec nice -n 15 commande & pour baisser sa priorité
  • commande & lance en background et rend le prompt immédiatement.
  • $! contient le PID de la dernière tâche background, capturez-le tout de suite.
  • Redirigez toujours stdout et stderr : commande > out.log 2>&1 &.
  • wait $PID attend la fin d'une tâche spécifique et expose son code dans $?.
  • disown $PID protège du SIGHUP de la déconnexion sans relancer la commande ; un exit seul ne tue pas une tâche qui tourne.

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