Codes de sortie et gestion des erreurs

ShellBeginner
Pratiquer maintenant

Introduction

Imaginez que chaque fois que vous demandez à quelqu’un d’effectuer une tâche, cette personne vous remette ensuite une petite carte.

  • Une carte verte (0) signifie : « J’ai parfaitement réussi. »
  • Une carte rouge (1-255) signifie : « Quelque chose s’est mal passé. »

Sous Linux, chaque commande fonctionne exactement de cette manière. On appelle cela un code de sortie ou un statut de sortie.

  • 0 : réussite.
  • Not 0 : échec.

La plupart des débutants ignorent ces codes, car ils restent généralement invisibles tant que vous ne demandez pas à les consulter. Les spécialistes des scripts les surveillent attentivement, car le statut de sortie est l’un des principaux moyens dont dispose le shell pour signaler la réussite ou l’échec entre les commandes et les scripts.

Il s’agit d’un principe fondamental de la conception Unix : de petits programmes communiquent entre eux au moyen de conventions simples. Le texte circule via la sortie standard, tandis que la réussite ou l’échec est transmis par le statut de sortie. C’est pourquoi les codes de sortie sont si importants dans l’automatisation.

Dans ce lab, vous apprendrez à lire ces cartes secrètes à l’aide de la variable $? et à arrêter vos scripts avant qu’ils ne causent des problèmes.

Vérifier le statut d’une commande avec $?

Comment afficher ce « bulletin » invisible ? Il suffit de consulter une variable spéciale appelée $? juste après l’exécution d’une commande.

Commençons par observer une réussite.

Ouvrez votre terminal et affichez la liste de vos fichiers :

ls -l

La commande a fonctionné, n’est-ce pas ? Demandons maintenant : « Quel a été le score ? »

echo $?

Vous devriez voir 0. Dans la logique de Linux, 0 représente le nombre d’erreurs. Zéro erreur signifie une réussite parfaite.

Provoquons maintenant un échec. Essayez d’afficher un fichier qui n’existe pas :

ls ghosts.txt

Linux indique qu’il ne trouve pas ce fichier. Consultez maintenant le score :

echo $?

Vous verrez 2. Cette valeur n’est pas 0 : la commande a donc échoué.

Le nombre exact différent de zéro peut varier selon la commande et la situation. Pour l’instant, retenez la règle essentielle : 0 signifie que la commande a réussi, et toute autre valeur signifie qu’elle a échoué. Plus tard, en travaillant avec des scripts et des outils, vous verrez que certains programmes utilisent différents codes non nuls pour décrire différents types de problèmes.

Règle essentielle : $? est une mémoire à court terme. Cette variable ne mémorise que la toute dernière opération effectuée. Si vous exécutez ls (échec), puis echo "hello", et que vous consultez ensuite $?, vous verrez 0, car la commande echo a réussi ! Vous devez donc vérifier $? immédiatement.

Créer un script qui échoue

Voici la zone à risque. Par défaut, un script ignore les cartes rouges : il poursuit simplement son exécution.

Imaginez un script qui effectue les opérations suivantes :

  1. Créer une sauvegarde.
  2. Supprimer les fichiers d’origine.

Si l’étape 1 échoue parce que la sauvegarde est pleine, l’étape 2 s’exécute quand même et vous perdez tout.

Simulons ce « script aveugle ».

Créez copy_script.sh :

nano copy_script.sh

Saisissez ce code. Il essaie de copier un fichier inexistant, puis annonce que l’opération a réussi.

#!/bin/bash

## Attempt to copy a ghost
cp ghost_file.txt destination.txt

## Print a happy message
echo "Script finished execution"

Enregistrez le fichier et quittez l’éditeur. Rendez ensuite le script exécutable :

chmod +x copy_script.sh

Exécutez-le :

./copy_script.sh

Vous voyez le message d’erreur de cp, puis le message « Script finished execution ». Le script a rencontré une erreur, mais il a continué son exécution !

Consultez le score du script lui-même :

echo $?

La commande renvoie 0. Pourquoi ? Parce que la dernière commande (echo) a réussi. Ce script ment : sa tâche principale a échoué, mais il a signalé une réussite au système.

Retenez cette leçon importante : un script shell possède lui aussi un statut de sortie. Si vous ne prévoyez rien de particulier, ce statut devient souvent celui de la dernière commande exécutée. Un script peut donc masquer accidentellement un échec survenu plus tôt.

Mettre en place la gestion des erreurs

Nous devons apprendre à notre script à s’arrêter au feu rouge.

Nous utilisons généralement la structure suivante : « Exécuter la commande X. Si son code de sortie n’est pas égal à 0, alors signaler une erreur. »

La syntaxe [ $? -ne 0 ] utilise la commande test, écrite ici sous sa forme entre crochets. Pour les nombres, -ne signifie « différent de ». Le shell pose donc la question suivante : « Le statut de sortie de la commande précédente est-il différent de zéro ? »

Modifiez votre script copy_script.sh :

nano copy_script.sh

Remplacez son contenu par :

#!/bin/bash

cp ghost_file.txt destination.txt

## Check if the score is NOT equal (-ne) to 0
if [ $? -ne 0 ]; then
  echo "Error: The copy operation failed!"
  exit 1
fi

echo "Script finished execution"

Décryptage :

  • if [ $? -ne 0 ] : le garde vérifie la carte.
  • exit 1 : le bouton rouge. Cette commande arrête immédiatement le script et définit le score global à 1 (erreur).

La commande exit termine le script shell en cours et renvoie ce nombre à ce qui l’a lancé, par exemple votre terminal, un autre script ou un système d’automatisation. Autrement dit, vous ne faites pas qu’arrêter l’exécution localement : vous transmettez également le statut au monde extérieur.

Enregistrez le fichier et quittez l’éditeur.

Exécutez de nouveau le script :

./copy_script.sh

Le script affiche l’erreur, puis s’arrête. Il n’affiche pas le message « Script finished execution ».

Consultez le score :

echo $?

La valeur est 1. Le script signale maintenant honnêtement son échec.

Résumé

Vous avez appris à comprendre le langage secret des commandes.

Dans ce lab, vous avez pratiqué les points suivants :

  1. Lire les bulletins : utiliser $? pour vérifier si une commande a réussi (0) ou échoué (1-255).
  2. Démasquer les scripts trompeurs : constater qu’un script peut masquer des erreurs si vous ne vérifiez pas attentivement son statut.
  3. Jouer le rôle de l’arbitre : utiliser exit 1 pour arrêter le jeu lorsqu’une faute survient.

Ce modèle « vérifier et quitter » fait la différence entre un script fragile et un script professionnel.