web-dev-qa-db-fra.com

Comment intercepter le code de sortie dans le script Bash

Il y a beaucoup de points de sortie dans mon code bash. J'ai besoin de faire un travail de nettoyage à la sortie, j'ai donc utilisé trap pour ajouter un rappel pour la sortie comme ceci:

trap "mycleanup" EXIT

Le problème est qu'il existe différents codes de sortie, j'ai besoin de faire des travaux de nettoyage correspondants. Puis-je obtenir le code de sortie dans mycleanup?

40
Dagang

Je pense que vous pouvez utiliser $? pour obtenir le code de sortie.

46
bmk

La réponse acceptée est fondamentalement correcte, je veux juste clarifier les choses.

L'exemple suivant fonctionne bien:

#!/bin/bash

cleanup() {
    rv=$?
    rm -rf "$tmpdir"
    exit $rv
}

tmpdir="$(mktemp)"
trap "cleanup" INT TERM EXIT
# Do things...

Mais vous devez être plus prudent si vous effectuez un nettoyage en ligne, sans fonction. Par exemple, cela ne fonctionnera pas:

trap "rv=$?; rm -rf $tmpdir; exit $rv" INT TERM EXIT

Au lieu de cela, vous devez échapper au $rv et $? variables:

trap "rv=\$?; rm -rf $tmpdir; exit \$rv" INT TERM EXIT

Vous pourriez également vouloir vous échapper $tmpdir, car il sera évalué lorsque la ligne d'interruption sera exécutée et si la valeur tmpdir change plus tard, cela ne vous donnera pas le comportement attendu.

Edit: Utilisez shellcheck pour vérifier vos scripts bash et être conscient de problèmes comme celui-ci.

46
Paul Tobias

J'ai trouvé qu'il était préférable de séparer le piège EXIT du piège pour les autres signaux

Exemple de script de test d'interruption ...

umask 77
tmpfile=`tmpfile.$$`
trap 'rm -f "$tmpfile"' EXIT
trap 'exit 2' HUP INT QUIT TERM

touch $tmpfile
read -r input 

exit 10

Le fichier temporaire est nettoyé. La valeur de sortie de fichier de 10 est préservée! Les interruptions entraînent une valeur de sortie de 2

Fondamentalement, tant que vous n'utilisez pas "exit" dans un piège EXIT, il sortira avec la valeur de sortie d'origine préservée.

À CÔTÉ: Notez la citation dans le piège EXIT. Cela me permet de modifier le fichier à nettoyer pendant la durée de vie des scripts. J'inclus souvent un test pour l'existence du fichier $ tmp avant d'essayer de le supprimer, donc je n'ai même pas besoin de le définir au début du script, seulement avant de le créer.

6
anthony