Zum Inhalt springen
System

Set -e en Bash : comprendre pourquoi certaines erreurs n’arrêtent pas le script

Avatar illustré de Julien Macé 2 Min. Lesezeit
Illustration Linux d’un script Bash qui sépare les erreurs des chemins d’exécution valides
Illustration Linux d’un script Bash qui sépare les erreurs des chemins d’exécution valides

Un script Bash peut continuer après une commande en échec, ou s’arrêter à un endroit que vous n’aviez pas prévu. C’est tout le piège de set -e : l’option ne transforme pas toutes les erreurs en arrêt immédiat. Elle dépend du contexte dans lequel la commande est exécutée.

Dans ce guide, vous allez voir ce que set -e couvre réellement, pourquoi les conditions et les pipelines changent son comportement, et comment ajouter set -u ou pipefail sans rendre le script impossible à diagnostiquer.

n
Illustration Linux d’un script Bash qui sépare les erreurs des chemins d’exécution valides
n nn

Ce que set -e arrête réellement

Avec set -e, Bash quitte généralement le script lorsqu’une commande simple renvoie un code différent de zéro. Exemple :

#!/usr/bin/env bash
set -e

printf 'Avant l’erreurn'
false
printf 'Cette ligne ne sera pas exécutéen'

La commande false renvoie 1. Le script s’arrête donc avant le deuxième printf. Vous pouvez vérifier le code de sortie avec echo $? quand le script ne s’est pas interrompu, ou en lançant le script puis printf 'Code : %sn' "$?" depuis le shell appelant.

Les exceptions qui piègent les scripts

set -e ne s’applique pas de la même façon dans une condition. C’est logique pour un test : une commande peut échouer parce que vous cherchez justement à savoir si elle échoue.

#!/usr/bin/env bash
set -e

if grep -q 'active' /etc/my-service.conf; then
  printf 'Option activen'
else
  printf 'Option absenten'
fi

printf 'Le script continue icin'

Dans cet exemple, grep peut renvoyer 1 sans arrêter le script, car il est utilisé comme condition du if. Le même principe concerne while, until, les tests placés après ! et certaines commandes d’un opérateur && ou ||. Ne considérez donc pas set -e comme un mécanisme de contrôle complet.

Pour une erreur attendue, traitez-la explicitement. Cela rend la décision visible :

if ! mkdir /var/lib/mon-service/cache; then
  printf 'Impossible de créer le cachen' >&2
  exit 1
fi

Pourquoi pipefail est souvent nécessaire

Sans option supplémentaire, le statut d’un pipeline correspond souvent à celui de sa dernière commande. Une erreur au début peut donc passer inaperçue :

set -e

cat /fichier-inexistant | sort | head

Ajoutez set -o pipefail si l’échec d’une commande située dans le pipeline doit faire échouer l’ensemble :

set -e
set -o pipefail

cat /fichier-inexistant | sort | head
printf 'Cette ligne ne sera pas atteinten'

Testez ce changement sur un poste ou un environnement de préproduction. Un pipeline qui exploite volontairement un code de sortie non nul doit être placé dans une condition ou capturé explicitement, sinon pipefail peut interrompre un traitement légitime.

Ajouter set -u sans masquer la cause

set -u arrête l’utilisation d’une variable non définie. C’est utile pour repérer une faute de nom ou un argument oublié :

set -u

config_file="${1:-}"
if [[ -z "$config_file" ]]; then
  printf 'Usage : %s fichier.confn' "$0" >&2
  exit 2
fi

printf 'Lecture de %sn' "$config_file"

Le paramètre ${1:-} fournit une valeur vide si le premier argument n’existe pas. Vous pouvez ensuite afficher un message d’usage plutôt que laisser Bash signaler une variable absente au milieu du traitement.

Une base stricte à tester avant déploiement

Pour un nouveau script, je pars généralement de cette base, puis je vérifie chaque commande qui peut échouer normalement :

#!/usr/bin/env bash
set -euo pipefail

config_file="${1:-}"
if [[ -z "$config_file" ]]; then
  printf 'Usage : %s fichier.confn' "$0" >&2
  exit 2
fi

if [[ ! -r "$config_file" ]]; then
  printf 'Fichier illisible : %sn' "$config_file" >&2
  exit 1
fi

printf 'Configuration prête : %sn' "$config_file"

Avant de le lancer via cron ou systemd, utilisez bash -n script.sh pour vérifier la syntaxe, puis exécutez-le avec un fichier de test. Ajoutez temporairement set -x si vous devez suivre les commandes réellement exécutées, mais évitez de l’activer autour de secrets ou de mots de passe.

set -e est utile pour refuser les échecs silencieux, pas pour éviter toute gestion d’erreur. Les commandes attendues dans des conditions, les pipelines et les retours métier doivent rester traités explicitement. C’est cette vérification qui rend le script fiable, pas la seule présence de set -euo pipefail.

Teilen Facebook X WhatsApp LinkedIn Pinterest Reddit E-Mail