Comment modifier le comportement des scripts sur les signaux à l'aide de pièges à bash

Comment modifier le comportement des scripts sur les signaux à l'aide de pièges à bash

Objectif

L'objectif de ce tutoriel est de décrire comment utiliser la coquille bash piège intégré pour rendre nos scripts capables d'effectuer certaines actions lorsqu'ils reçoivent un signal ou dans d'autres situations spécifiques.

Exigences

  • Aucune exigence spéciale

Difficulté

FACILE

Conventions

  • # - nécessite que les commandes Linux soient exécutées avec des privilèges racine
    directement en tant qu'utilisateur racine ou en utilisant Sudo commande
  • $ - Exige que les commandes Linux soient exécutées en tant qu'utilisateur non privilégié régulier

Introduction

Lors de la rédaction de scripts qui visent à fonctionner pendant un temps considérable, il est très important d'augmenter leur robustesse en les faisant réagir aux signaux du système, en exécutant des actions spécifiques lorsque certains d'entre eux sont reçus. Nous pouvons accomplir cette tâche en utilisant le bash piège construit.

Que sont les pièges?

Un piège est un mécanisme bash qui permet de personnaliser un comportement de script lorsqu'il reçoit un signal. Ceci est très utile, par exemple, pour s'assurer que le système est toujours dans un état cohérent. Imaginez que vous avez écrit un script qui, au cours de son exécution, doit créer des répertoires: si, par exemple, un signal Sigint lui est envoyé, le script sera interrompu, laissant derrière lui les répertoires qu'il a créés. En utilisant des pièges, nous pouvons gérer des situations comme celle-ci.

Syntaxe de piège

La syntaxe du piège est très simple et facile à comprendre: nous devons d'abord appeler le piège intégré, suivi de l'exécution des actions, alors nous devons spécifier le (s) signal (s) auquel nous voulons réagir:

trap [-lp] [[arg] sigSpec]

Voyons ce que le possible piège Les options sont pour.

Lorsqu'il est utilisé avec le -l Flag, la commande Trap affichera simplement une liste de signaux associés à leurs chiffres. C'est la même sortie que vous pouvez obtenir en cours d'exécution tuer -l commande:

$ TRAP -L 1) SHIPUP 2) SIGINT 3) Sigquit 4) Sigill 5) Sigtrap 6) Sigabrt 7) Sigbus 8) Sigfpe 9) Sigkill 10) Sigusr1 11) Sigsegv 12) Sigusr2 13) Sigpipe 14) Sigalrm 15) Sigtron 16) ) Sigstkflt 17) Sigchld 18) Sigconont 19) Sigstop 20) Sigtstp 21) Sigttin 22) Sigttou 23) Sigurg 24) Sigxcpu 25) Sigxfsz 26) Sigvtalrm 27) Sigprof 28) Sigwinch 29) 35) Sigrtmin + 1 36) Sigrtmin + 2 37) Sigrtmin + 3 38) Sigrtmin + 4 39) Sigrtmin + 5 40) Sigrtmin + 6 41) Sigrtmin + 7 42) Sigrtmin + 8 43) Sigrtmin + 9 44) Sigrtmin + 10 45) Sigrtmin + 11 46) Sigrtmin + 12 47) Sigrtmin + 13 48) Sigrtmin + 14 49) Sigrtmin + 15 50) SigrtMax-14 51) SigrtMax-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) Sigrtmax-9 56) Sigrtmax-8 57) Sigrtmax-7 58) Sigrtmax-6 59) Sigrtmax-5 60) Sigrtmax-4 61) Sigrtmax-3 62) Sigrtmax-2 63) SIGRTMAX-1 64) SIGRTMAX 

Il est vraiment important de spécifier qu'il est possible de réagir uniquement aux signaux qui permettent au script de répondre: le Sigkill et Sigstop Les signaux ne peuvent pas être capturés, bloqués ou ignorés.

En dehors des signaux, les pièges peuvent également réagir à certains pseudo-signal comme la sortie, l'erreur ou le débogage, mais nous les verrons en détail plus tard. Pour l'instant, n'oubliez pas qu'un signal peut être spécifié soit par son numéro, soit par son nom, même sans le Sig préfixe.

À propos de -p Option maintenant. Cette option n'a sens que lorsqu'une commande n'est pas fournie (sinon elle produira une erreur). Lorsque le piège est utilisé avec lui, une liste des pièges précédemment définis sera affiché. Si le nom ou le numéro du signal est spécifié, seul l'ensemble de pièges pour ce signal spécifique sera affiché, sinon aucune distinction ne sera faite, et tous les pièges seront affichés:

$ trap 'echo "Sigint attrapé!"'Sigint

Nous définissons un piège pour attraper le signal Sigint: il affichera simplement le message «Sigint pris» à l'écran lorsque le signal donné sera reçu par la coque. Si nous utilisons maintenant Trap avec l'option -p, il affichera le piège que nous venons de définir:

$ trap -p trap - 'echo "Sigint attrapé!"'Sigint 

Soit dit en passant, le piège est désormais «actif», donc si nous envoyons un signal Sigint, soit en utilisant la commande kill, ou avec le raccourci Ctrl-C, la commande associée dans le piège sera exécutée (^ c est juste imprimée parce que de la combinaison clé):

^ Csigint attrapé!

Piège en action

Nous allons maintenant écrire un script simple pour montrer le piège en action, le voici:

#!/ usr / bin / env-bash # # un script simple pour démontrer comment le trap fonctionne # set -e set -u set -o tuypail trap 'echo "signal capturé, nettoyage…"; rm -i linux_tarball.le goudron.XZ 'SIGINT SIGTERM ECHO "Téléchargement du tarball…" WGET -O Linux_Tarball.le goudron.xz https: // cdn.noyau.org / pub / linux / noyau / v4.x / linux-4.13.5.le goudron.xz &> / dev / null
Copie

Le script ci-dessus essaie simplement de télécharger le dernier tarball du noyau Linux dans le répertoire à partir de ce qu'il est lancé en utilisant wget. Pendant la tâche, si les signaux SIGINT ou SIGTERM sont reçus (remarquez comment vous pouvez spécifier plus d'un signal sur la même ligne), le fichier partiellement téléchargé sera supprimé.

Dans ce cas, la commande est en fait deux: le premier est le écho qui imprime le message à l'écran, et le second est le réel RM Commande (nous l'avons fourni l'option -i, donc il demandera à la confirmation de l'utilisateur avant le retrait), et ils sont séparés par un point-virgule. Au lieu de spécifier les commandes de cette façon, vous pouvez également appeler des fonctions: cela vous donnerait plus de réutilisation. Notez que si vous ne fournissez aucune commande, le ou les signaux seront simplement ignorés!

Ceci est la sortie du script ci-dessus lorsqu'il reçoit un signal Sigint:

$ ./ fetchlinux.SH Téléchargement du tarball… ^ csignal capturé, nettoyage… RM: supprimer le fichier régulier 'Linux_tarball.le goudron.xz '? 

Une chose très importante à retenir est que lorsqu'un script est terminé par un signal, comme ci-dessus, son statut existant sera le résultat de 128 + le numéro de signal. Comme vous pouvez le voir, le script ci-dessus, terminé par un Sigint, a un statut de sortie de 130:

$ echo $? 130 

Enfin, vous pouvez désactiver un piège simplement en appelant piège suivi par le - signe, suivi du (s) nom ou numéro de signal:

Trap - Sigint Sigterm

Les signaux reprendront la valeur qu'ils avaient à l'entrée de la coquille.

Pseudo-signaux

Comme déjà mentionné ci-dessus, le piège peut être défini non seulement pour les signaux qui permet au script de répondre, mais aussi à ce que nous pouvons appeler des «pseudo-signaux». Ce ne sont pas techniquement des signaux, mais correspondent à certaines situations qui peuvent être spécifiées:

SORTIE

Quand SORTIE est spécifié dans un piège, la commande du piège sera exécutée à la sortie du shell.

SE TROMPER

Cela entraînera l'exécution de l'argument du piège lorsqu'une commande renvoie un statut de sortie non nul, à quelques exceptions (la même de l'option shell errexit): la commande ne doit pas faire partie d'un alors que ou jusqu'à boucle; il ne doit pas faire partie d'un si construire, ni faire partie d'un && ou || Liste, et sa valeur ne doit pas être inversée en utilisant le ! opérateur.

DÉBOGUER

Cela entraînera l'exécution de l'argument du piège avant chaque commande simple,
pour, cas ou sélectionner commandes, et avant la première commande dans les fonctions shell.

RETOUR

L'argument du piège est exécuté après une fonction ou un script provenant en utilisant source ou la . commande.

Tutoriels Linux connexes:

  • Comment propager un signal aux processus d'enfants à partir d'un bash…
  • Comment effectuer des opérations d'administration avec Ansible…
  • Comment installer le signal sur Linux
  • Choses à installer sur Ubuntu 20.04
  • Comment utiliser la commande killall sur Linux
  • Comment sortir du script bash
  • Choses à faire après l'installation d'Ubuntu 20.04 Focal Fossa Linux
  • Commandes Linux: les 20 meilleures commandes les plus importantes que vous devez…
  • VirtualBox augmente la taille du disque sur Linux
  • Guide de dépannage général GNU / Linux pour les débutants