Comment le code de sortie de piège dans le script Bash
Question
Il sont nombreux points de sortie dans mon code bash. Je dois faire des travaux de nettoyage à la sortie, donc je piège pour ajouter un rappel pour la sortie comme ceci:
trap "mycleanup" EXIT
Le problème est là sont différents codes de sortie, je dois faire des travaux de nettoyage correspondant. Puis-je obtenir le code de sortie dans mycleanup?
La solution
Je pense que vous pouvez utiliser $?
pour obtenir le code de sortie.
Autres conseils
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 faire en ligne de nettoyage, 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 aux variables $rv
et $?
:
trap "rv=\$?; rm -rf $tmpdir; exit \$rv" INT TERM EXIT
Vous pouvez également échapper $tmpdir
, car il s'évalué lorsque la ligne de piège est exécuté et si la valeur de tmpdir
change plus tard que vous ne le comportement attendu donner.
Modifier. Utilisez shellcheck pour vérifier vos scripts bash et être au courant des problèmes comme celui-ci
Je l'ai trouvé il est préférable de piège séparé sortie du piège pour d'autres signaux
Exemple script de test piège ...
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 conservé! Interruptions conduisent à une valeur de sortie de 2
En fait, tant que vous n'utilisez pas « sortie » dans un piège EXIT, il se terminera avec la valeur de sortie d'origine préservée.
OPPOSITION: Notez la citation dans le piège EXIT. Cela me permet de modifier son besoins de fichiers à nettoyer pendant la durée de vie des scripts. Je comportent aussi souvent un test pour l'existence de la tmpfile $ avant d'essayer de l'enlever, donc je ne même pas besoin de le mettre au début du script, seulement avant de le créer.