279 votes

Gestion des erreurs en BASH

Quelle est votre méthode préférée pour gérer les erreurs en BASH ? Le meilleur exemple de gestion des erreurs en BASH que j'ai trouvé sur le web a été écrit par William Shotts, Jr à l'adresse suivante http://www.linuxcommand.org .

William Shotts, Jr suggère d'utiliser la fonction suivante pour la gestion des erreurs dans BASH :

#!/bin/bash

# A slicker error handling routine

# I put a variable in my scripts named PROGNAME which
# holds the name of the program being run.  You can get this
# value from the first item on the command line ($0).

# Reference: This was copied from <http://www.linuxcommand.org/wss0150.php>

PROGNAME=$(basename $0)

function error_exit
{

#   ----------------------------------------------------------------
#   Function for exit due to fatal program error
#       Accepts 1 argument:
#           string containing descriptive error message
#   ----------------------------------------------------------------

    echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2
    exit 1
}

# Example call of the error_exit function.  Note the inclusion
# of the LINENO environment variable.  It contains the current
# line number.

echo "Example of error with line number and message"
error_exit "$LINENO: An error has occurred."

Avez-vous une meilleure routine de gestion des erreurs que vous utilisez dans les scripts BASH ?

6voto

yukondude Points 8756

Une autre considération est le code de sortie à retourner. Juste " 1 "est assez standard, bien qu'il y ait une poignée de codes de sortie réservés que bash lui-même utilise Cette même page affirme que les codes définis par l'utilisateur devraient être compris entre 64 et 113 pour être conformes aux normes C/C++.

Vous pouvez également envisager l'approche du vecteur de bits qui mount utilise pour ses codes de sortie :

 0  success
 1  incorrect invocation or permissions
 2  system error (out of memory, cannot fork, no more loop devices)
 4  internal mount bug or missing nfs support in mount
 8  user interrupt
16  problems writing or locking /etc/mtab
32  mount failure
64  some mount succeeded

OR -L'association de ces codes permet à votre script de signaler plusieurs erreurs simultanées.

5voto

Olivier Delrieu Points 110

J'utilise le code piège suivant, il permet également de erreurs à tracer à travers les tuyaux et les commandes 'time'.

#!/bin/bash
set -o pipefail  # trace ERR through pipes
set -o errtrace  # trace ERR through 'time command' and other functions
function error() {
    JOB="$0"              # job name
    LASTLINE="$1"         # line of error occurrence
    LASTERR="$2"          # error code
    echo "ERROR in ${JOB} : line ${LASTLINE} with exit code ${LASTERR}"
    exit 1
}
trap 'error ${LINENO} ${?}' ERR

3voto

pjz Points 11925

J'ai utilisé

die() {
        echo $1
        kill $$
}

avant ; je pense que c'est parce que 'exit' échouait pour moi pour une raison quelconque. Les valeurs par défaut ci-dessus semblent être une bonne idée, cependant.

3voto

l0b0 Points 10719

Ce site m'a bien servi depuis un certain temps. Il imprime les messages d'erreur ou d'avertissement en rouge, une ligne par paramètre, et autorise un code de sortie optionnel.

# Custom errors
EX_UNKNOWN=1

warning()
{
    # Output warning messages
    # Color the output red if it's an interactive terminal
    # @param $1...: Messages

    test -t 1 && tput setf 4

    printf '%s\n' "$@" >&2

    test -t 1 && tput sgr0 # Reset terminal
    true
}

error()
{
    # Output error messages with optional exit code
    # @param $1...: Messages
    # @param $N: Exit code (optional)

    messages=( "$@" )

    # If the last parameter is a number, it's not part of the messages
    last_parameter="${messages[@]: -1}"
    if [[ "$last_parameter" =~ ^[0-9]*$ ]]
    then
        exit_code=$last_parameter
        unset messages[$((${#messages[@]} - 1))]
    fi

    warning "${messages[@]}"

    exit ${exit_code:-$EX_UNKNOWN}
}

3voto

Je ne sais pas si cela vous sera utile, mais j'ai modifié certaines des fonctions suggérées ici afin d'y inclure la vérification de l'erreur (code de sortie de la commande précédente). À chaque "vérification", je passe également en paramètre le "message" de l'erreur à des fins de journalisation.

#!/bin/bash

function error_exit
{

    if [ "$?" != "0" ]; then
        log.sh "$1"
        exit 1
    fi
}

Maintenant pour l'appeler dans le même script (ou dans un autre si j'utilise export -f error_exit) j'écris simplement le nom de la fonction et passe un message en paramètre, comme ceci :

#!/bin/bash

cd /home/myuser/afolder
error_exit "Unable to switch to folder"

rm *
error_exit "Unable to delete all files"

En utilisant ceci, j'ai pu créer un fichier bash vraiment robuste pour un processus automatisé et il s'arrêtera en cas d'erreurs et me notifiera (log.sh fera cela).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X