Lorsqu'un shell UNIX s'achève soit de lui-même soit par une erreur (interuption par ctrl+C, une erreur de syntaxe ou de commande, ...) il se peut que les répertoires ne soient pas propres ou remis en état.

En effet, surtout dans le cas d'une fin en erreur, en fonction de l'endroit où le script s'est arrêté, les générations de fichiers et/ou de données n'étant pas finies, tout n'est pas forcément propre et cohérent. Dan certains cas, il peut même être utile d'exécuter un autre script en cas d'erreur afin, par exemple, d'envoyer un message d'alerte, effectuer une restauration ou une sauvegarde, ...

Malheureusement,pour réaliser tout cela il faut pouvoir réagir en fonction du type d'arrêt de script. trap est la commande qui permet justement de faire cela.

Syntaxe

trap 'commande' liste_de_signaux

Le numéro de signal correspond à ceux qu'on obtient avec la commande kill -l. Avec trap on peut soit utiliser le signal, soit son numéro.

# kill -l
 1) HUP                                                                      23) WINCH
 2) INT                                                                      24) STOP
 3) QUIT                                                                     25) TSTP
 4) ILL                                                                      26) CONT
 5) TRAP                                                                     27) TTIN
 6) IOT                                                                      28) TTOU
 7) EMT                                                                      29) URG
 8) FPE                                                                      30) LOST
 9) KILL                                                                     31) RESERVED
10) BUS                                                                      32) DIL
11) SEGV                                                                     33) XCPU
12) SYS                                                                      34) XFSZ
13) PIPE                                                                     35) bad trap
14) ALRM                                                                     36) bad trap
15) TERM                                                                     37) RTMIN
16) USR1                                                                     38) RTMIN+1
17) USR2                                                                     39) RTMIN+2
18) CHLD                                                                     40) RTMIN+3
19) PWR                                                                      41) RTMAX-3
20) VTALRM                                                                   42) RTMAX-2
21) PROF                                                                     43) RTMAX-1
22) POLL                                                                     44) RTMAX
SignalSignification
HUPhangup : envoie un signal de réinitialisation
INTInterruption
QUITCore dump
ILLLe programme tente d'exécuter du code malformé, inconnu ou avec de mauvais privilèges
TRAPLe programme envoie un signal au débugger (message capturé)
IOTidem SIGABRT : interruption du programme
EMTemulator trap : un programme émulé ou virtualisé a posé problème
FPEfloating-point exception : le programme a réalisé une opération arithmétique erronée
KILLarrête le programme immédiatement
BUSLe programme a causé une erreur de bus
SEGVSegmentation fault : le programme fait référence à un mauvais emplacement de mémoire
SYSUn mauvais argument est passé en paramètre
PIPEUn programme tente d'écrire dans un pipe sans processus connecté à l'autre bout
ALRMLa limite de temps est dépassée
TERMEnvoie un signal au programme pour le terminer
USR1/USR2Envoie un signal dans des conditions définies par un utilisateur
CHLD/CLDchild : signal envoyé par un programme lorsqu'un processus fils est achevé
PWRpower : le système subit un problème d'alimentation
VTALRMvirtual alarm : signal envoyé lorsque le temps limite a été dépassé
PROFprofiler : signal envoyé lorsqu'un timer a expiré
POLLpolling : un problème est survenu lors d'un événement I/O asynchrone
WINCHwindow [size] change : signal envoyé au programme lorsque la fenêtre de contrôle change de taille
STOPsignal demandant au programme de se suspendre
TSTPtty stop : signal envoyé au programme lorsqu'un terminal suspend ses requêtes
CONTRedémarre un programme suspendu par STOP
TTINLe programme tente de lire tty alors qu'il est en arrière-plan
TTOULe programme tente d'écrire sur tty alors qu'il est en arrière-plan
URGUn socket a une donnée urgente à lire
LOSTLe verrou d'un fichier a été perdu
XCPULe programme a utilisé le CPU prend trop longtemps
XFSZLe fichier a dépassé la taille maximale autorisée
RTMIN/RTMIN+nreal-time minimum : signaux définis par l'application
RTMAX/RTMAX-nreal-time maximum : signaux définis par l'application

remarque

Il existe aussi des pseudo signaux comme le signal 0 (EXIT) qui est la valeur retournée par la fin sans erreur d'un script. C'est aussi la valeur retournée par le shell lors de la déconnexion.

La commande est soit une (liste de) commande(s) exécutée(s) en direct soit un appel de fonction.

Le commande trap sert dans deux cas bien distincts :

Exemples

empêcher l'interruption d'un programme

#!/bin/sh
trap "" 2 3 15 # ignorer les signaux
while :
do
echo "Entrez le mot de passe : \c"
read mdp
if [ "${mdp}" = "test" ]
then
echo "mot de passe valide !"
break
fi
done
trap 2 3 15 # revenir à l'état par défaut

Cet exemple montre que la boucle ne peut pas être interrompue, sauf par l'entrée du bon mot de passe. En effet, le script commence par mettre de côté les signaux en leur affectant une exécution vide. trap ne remettra en place correcte le contexte qui si la boucle s'achève avec succès (entrée du bon mot de passe). Ainsi, l'utilisateur, quoi qu'il fasse ne peut pas interrompre le programme.

ignorer un signal

trap "" 2 # ignorer le signal

ignorer un ensemble de signaux

trap "" 2 3 15 # ignorer les signaux

revenir à l'action par défaut

trap 2 # retablir la situation

utiliser les mnémoniques

trap "echo CTRL-C" INT # retablir la situation

exécuter un script à la déconnexion

Pour exécuter un script automatiquement à la déconnexion, il faut d'abord ajouter au fichier .profile :

trap "~/logoff" 0

Puis créer le script logoff en question :

#!/bin/sh
rm /tmp/*.tmp
clear
echo "Suppression des fichiers temporaires terminée"
echo "Déconnexion..."

Ne pas oublier de rendre le script exécutable...