Exec

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Shell scripting (bash builtin)
Commande exec
Contexte Deux usages distincts : remplacement du process courant, ou gestion de descripteurs de fichiers custom
Voir aussi Tee (duplication de flux)

exec est un builtin bash qui recouvre deux usages bien distincts et souvent confondus. Utilisé avec une commande (exec ls), il remplace le process shell courant par cette commande, sans fork ni retour possible. Utilisé avec une redirection seule (exec 3> fichier), il ouvre, redirige ou ferme un descripteur de fichier pour le shell courant, sans lancer aucune commande.

Remplacer le process courant

Sans redirection, exec suivi d'une commande remplace le shell en cours d'exécution par cette commande : le PID ne change pas, mais l'image du process est remplacée, et le script ne reprend jamais la main après.

#!/bin/bash
echo "préparation..."
exec /usr/bin/monprogramme --option
echo "cette ligne ne s'exécute jamais"

Cas d'usage typique : un script wrapper qui prépare l'environnement (variables, arguments, cd) puis délègue définitivement l'exécution à un vrai binaire, sans garder de process shell parent inutile en mémoire.

#!/bin/bash
export JAVA_HOME=/opt/java
cd /opt/tomcat
exec ./bin/catalina.sh run

Ici, une fois exec lancé, il n'y a plus de process bash intermédiaire : catalina.sh hérite directement du PID du script, ce qui simplifie la gestion des signaux (kill, systemd) puisqu'il n'y a plus qu'un seul process à surveiller au lieu de deux imbriqués.

⚠️ Ne pas utiliser exec ainsi s'il faut exécuter du code après la commande (nettoyage, log de fin, etc.) — dans ce cas, appeler la commande normalement (sans exec).

Descripteurs de fichiers personnalisés

Utilisé avec une redirection seule (sans commande), exec agit sur les descripteurs de fichiers du shell courant lui-même : on peut en ouvrir un nouveau, écrire dedans depuis n'importe quelle commande suivante, puis le refermer.

# ouvrir le descripteur 3 en écriture vers un fichier
exec 3> dump.log

# toute commande peut ensuite écrire dedans avec >&3
ls -l >&3
echo "fin du traitement" >&3

# fermer le descripteur une fois terminé
exec 3>&-

Le descripteur 3 reste ouvert pour tout le reste du script (ou jusqu'à sa fermeture explicite), contrairement à une redirection classique (commande > fichier) qui ne vaut que pour cette commande.

Logguer sans rediriger toute la sortie du script

Utile quand seule une partie des commandes doit être tracée dans un fichier, sans toucher à la sortie standard du reste du script qui continue de s'afficher normalement à l'écran :

exec 3> /var/log/monscript.log

echo "démarrage" # affiché à l'écran
rsync -av /src /dst >&3 2>&1 # tracé uniquement dans le fichier
echo "terminé" # affiché à l'écran

exec 3>&-

Dupliquer stdout/stderr avec tee

Combiné à Tee et à la substitution de process, exec permet de dupliquer toute la sortie du script à la fois vers l'écran et vers un fichier, pour le reste de son exécution :

exec > >(tee -a /var/log/monscript.log) 2>&1

echo "tout ce qui suit part à la fois vers l'écran et vers le fichier"

Cette fois, exec ne redirige pas vers un descripteur custom mais remplace directement le stdout (1) et le stderr (2) du shell courant, en s'appuyant sur la substitution de process >(...) pour brancher tee derrière.

Voir aussi

  • Tee — duplication de flux, utilisé en combinaison avec exec pour journaliser toute la sortie d'un script