Recherche…


Syntaxe

  • action piège sigspec ... # Exécuter "action" sur une liste de signaux
  • piège sigspec ... # Omettre l'action réinitialise les traps pour les signaux

Paramètres

Paramètre Sens
-p Liste des pièges actuellement installés
-l Liste des noms de signaux et numéros correspondants

Remarques

Le trap utilitaire est une enveloppe spéciale intégrée. Il est défini dans POSIX , mais bash ajoute également des extensions utiles.

Les exemples compatibles avec POSIX commencent par #!/bin/sh et les exemples commençant par #!/bin/bash utilisent une extension bash.

Les signaux peuvent être soit un numéro de signal, un nom de signal (sans le préfixe SIG), soit le mot-clé spécial EXIT .

Ceux garantis par POSIX sont:

Nombre prénom Remarques
0 SORTIE Toujours exécuter à la sortie du shell, quel que soit le code de sortie
1 SIGHUP
2 SIGINT C'est ce que ^C envoie
3 SIGQUIT
6 SIGABRT
9 SIGKILL
14 SIGALRM
15 SIGTERM C'est ce que kill envoie par défaut

SIGINT de capture ou Ctl + C

Le piège est réinitialisé pour les sous-couches, de sorte que le sleep agira toujours sur le signal SIGINT envoyé par ^C (généralement en quittant), mais le processus parent (c'est-à-dire le script shell) ne le fera pas.

#!/bin/sh

# Run a command on signal 2 (SIGINT, which is what ^C sends)
sigint() {
    echo "Killed subshell!"
}
trap sigint INT

# Or use the no-op command for no output
#trap : INT

# This will be killed on the first ^C
echo "Sleeping..."
sleep 500

echo "Sleeping..."
sleep 500

Et une variante qui vous permet encore de quitter le programme principal en appuyant deux fois sur ^C :

last=0
allow_quit() {
    [ $(date +%s) -lt $(( $last + 1 )) ] && exit
    echo "Press ^C twice in a row to quit"
    last=$(date +%s)
}
trap allow_quit INT

Introduction: nettoyer les fichiers temporaires

Vous pouvez utiliser la commande trap pour "piéger" les signaux; c'est l'équivalent shell de l'appel signal() ou sigaction() en C et de la plupart des autres langages de programmation pour capter les signaux.

L'une des utilisations les plus courantes de trap est de nettoyer les fichiers temporaires à la sortie attendue et inattendue.

Malheureusement, pas assez de scripts shell le font :-(

#!/bin/sh

# Make a cleanup function
cleanup() {
  rm --force -- "${tmp}"
}

# Trap the special "EXIT" group, which is always run when the shell exits.
trap cleanup EXIT

# Create a temporary file
tmp="$(mktemp -p /tmp tmpfileXXXXXXX)"

echo "Hello, world!" >> "${tmp}"

# No rm -f "$tmp" needed. The advantage of using EXIT is that it still works
# even if there was an error or if you used exit.

Cumulez une liste de trappes à exécuter à la sortie.

Avez-vous déjà oublié d'ajouter un trap pour nettoyer un fichier temporaire ou d'autres travaux à la sortie?

Avez-vous déjà mis un piège qui a annulé un autre?

Ce code facilite l'ajout d'éléments à la sortie d'un élément à la fois, plutôt que d'avoir une seule instruction trap quelque part dans votre code, ce qui peut être facile à oublier.

# on_exit and add_on_exit
# Usage:
#   add_on_exit rm -f /tmp/foo
#   add_on_exit echo "I am exiting"
#   tempfile=$(mktemp)
#   add_on_exit rm -f "$tempfile"
# Based on http://www.linuxjournal.com/content/use-bash-trap-statement-cleanup-temporary-files
function on_exit()
{
    for i in "${on_exit_items[@]}"
    do
        eval $i
    done
}
function add_on_exit()
{
    local n=${#on_exit_items[*]}
    on_exit_items[$n]="$*"
    if [[ $n -eq 0 ]]; then
        trap on_exit EXIT
    fi
}

Tuer les processus de l'enfant à la sortie

Les expressions pièges ne doivent pas nécessairement être des fonctions ou des programmes individuels, elles peuvent également être des expressions plus complexes.

En combinant jobs -p et kill , nous pouvons tuer tous les processus enfants générés par le shell à la sortie:

trap 'jobs -p | xargs kill' EXIT

réagir au changement de taille de la fenêtre des terminaux

Il y a un signal WINCH (WINdowCHange), qui est déclenché quand on redimensionne une fenêtre de terminal.

declare -x rows cols
 
update_size(){
  rows=$(tput lines) # get actual lines of term
  cols=$(tput cols)  # get actual columns of term
  echo DEBUG terminal window has no $rows lines and is $cols characters wide
}

trap update_size WINCH


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow