Comment exécuter une commande avant la fermeture d'un script Bash?

119

Si un script Bash a set -e, et une commande dans le script renvoie une erreur, comment puis-je effectuer un nettoyage avant la fermeture du script?

Par exemple:

#!/bin/bash
set -e
mkdir /tmp/foo
# ... do stuff ...
rm -r /tmp/foo

Comment puis-je m'assurer que cela /tmp/fooest supprimé, même si l'une des commandes ... do stuff ...échoue?

David Wolever
la source

Réponses:

193

Voici un exemple d'utilisation de trap:

#!/bin/bash -e

function cleanup {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}

trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails

Production:

dbrown@luxury:~ $ sh traptest
t: line 9: asdffdsa: command not found
Removing /tmp/foo
dbrown@luxury:~ $

Notez que même si la ligne asdffdsa a échoué, le nettoyage était quand même exécuté.

devguydavid
la source
11

Depuis la bashpage de manuel (concernant les builtins):

trap [-lp] [[arg] sigspec ...]
La commande arg doit être lue et exécutée lorsque le shell reçoit le (s) signal (s) sigspec.

Ainsi, comme indiqué dans la réponse d'Anon. , Appelez traptôt dans le script pour configurer le gestionnaire que vous désirez sur ERR.

dmckee --- chaton ex-modérateur
la source
Exécutez help trappour voir de l'aide sur le fichier intégré.
Flimm
8

De la référence pour set:

-e

Quittez immédiatement si une commande simple (voir section 3.2.1 Commandes simples) se termine avec un état différent de zéro, sauf si la commande qui échoue fait partie d'une boucle jusqu'à ou while, une partie d'une instruction if, une partie d'un && ou || list, ou si l'état de retour de la commande est inversé à l'aide de!. Un trap sur ERR, s'il est défini, est exécuté avant la sortie du shell.

(Je souligne le mien).

Anon.
la source
Cela pourrait valoir la peine d'ajouter "-E" lors de l'utilisation de "-e", voir vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail
Max Barraclough
3

shversion de la réponse de devguydavid .

#!/bin/sh
set -e
cleanup() {
  echo "Removing /tmp/foo"
  rm  -r /tmp/foo
}
trap cleanup EXIT
mkdir /tmp/foo
asdffdsa #Fails

réf: shellscript.sh

Saftever
la source
POSIXFais moi rire. :) Excellent site d'enseignement auquel vous avez également lié.
Cometsong