Wenn der User dein Script mit CTRL-C abbricht, ist ein kontrolliertes Beenden und Aufräumen nicht mehr möglich. Dies lässt sich mit trap verhindern.

| 1 | Einführung |
|---|---|
| 2 | Der bash Prompt |
| 3 | key bindings |
| 4 | Der Startvorgang |
| 5 | Environment Variablen |
| 6 | builtin commands |
| 7 | Arbeiten mit Dateien |
| 8 | nano |
| 9 | bash Scripting |
| 10 | Variablen |
| 11 | Verzweigungen (if) |
| 12 | Schleifen |
| 13 | Kommandozeilenparameter |
| 14 | exit Codes bash Tutorial Teil 14 |
| 15 | von der Idee zum Script |
| 16 | grep |
| 17 | Piping und Redirection |
| 18 | tee |
| 19 | alias |
| 20 | Der Shebang |
| 21 | Das sed Kommando |
| 22 | cd Kommando |
| 23 | case Verzweigungen |
| 24 | Arrays |
| 25 | Signale und trap |
| 26 | Heredoc |
| 27 | getopt |
Signale
Für bestimmte Ereignisse sendet die bash ein Signal an dein Script, auf das du mit dem trap Kommando reagieren kannst.
Die verfügbaren Signale sind von Betriebssystem zu Betriebssystem unterschiedlich. Du kannst sie dir mit
trap -lanzeigen lassen.

Die Namen aller Signale beginnen mit „SIG“, danach folgt abgekürzt, was signalisiert wird. Das ist etwas kryptisch. Das Signal SIGHUP ist eher noch historisch erhalten geblieben. Es signalisiert einen Hang Up, also, wenn die Datenleitung beendet wurde. Es stammt noch aus der Zeit der Einwählmodems.
SIGKILL wird signalisiert, wenn ein Prozess über das kill Kommando abgeschossen wird. Dieses ist nicht abfangbar.
Uns interessiert heute das SIGTERM, mit dem unserem Script signalisiert wird, dass es beendet wird.
Ausgangslage
Betrachten wir mal dieses Script:
#! /usr/bin/bash
touch /tmp/testfile
sleep 10
echo "Ende der Arbeit"
rm /tmp/testfile
Es legt unter /tmp eine temporäre Datei namens testfile an. Das sleep 10 steht für eine beliebige langwierige Aufgabe, die das Script erledigt. Wenn diese durchlaufen ist, wird die temporäre Datei wieder gelöscht.
Letzteres passiert aber nicht, wenn der User das Script mit CTRL-C abbricht. Dann wird es beendet, bevor es das rm Kommando ausführen kann. Die Datei bleibt dann so lange stehen, bis sie manuell entfernt wird. Jetzt mal dir aus, ein Script würde 1000 temporäre Dateien von mehreren 100 KByte Grösse anlegen. Dann würde die Speicherkarte das Raspis rasch volllaufen.

SIGINT abfangen
Lass uns das mal verbessern. Wir benötigen eine Funktion zum Aufräumen und binden diese an das Signal.
#! /usr/bin/bash
cleanup() {
echo "Programmende signalisiert."
rm /tmp/testfile
}
trap cleanup exit
touch /tmp/testfile
sleep 10
echo "Ende der Arbeit"
Die Funktion cleanup() wird durch trap cleanup exit an das Signal gekoppelt. Immer, wenn das Script beendet wird, wird jetzt unsere Funktion aufgerufen. Dadurch können wir das Löschen von testfile in diese Funktion verlagern.

Auch, wenn das Programm ganz regulär durchläuft, wird nachher cleanup() aufgerufen.

In der Überschrift steht SIGINT, die Scripts trappen aber exit. Warum ist das so? Mit SIGTERM signalisiert der Kernel das Ende des Scripts. Wir reagieren aber dann immer so als läge ein reguläres Programmende vor. Dadurch spart man sich ein Keyword.
Ablauf eines Signals
Was passiert jetzt eigentlich genau wenn du CTRL-C drückst? Der Kerneltreiber erkennt dies und sendet dem Terminaltreiber (also der bash) das SIGINT. Diese sorgt dafür, dass der Vordergrundprozess (also unser Script beendet wird. Wodurch das exit Signal ausgelöst wird, auf das wir dann reagieren.
trap ohne spezielle Funktion
trap führt immer den Programmcode aus, der vor dem Signalnamen steht. Das kann wie oben eine spezielle Funktion sein. Du kannst aber auch andere Kommandos dort platzieren.
#! /usr/bin/bash
trap "echo vorbei" SIGINT
touch /tmp/testfile
sleep 10
echo "Ende der Arbeit"
In dieser Variante wird bei SIGINT nur echo vorbei ausgeführt. Eine spezielle Funktion zur Behandlung des Signals ist nicht notwendig.Achte darauf, wie die Anführungszeichen gesetzt sind. Das gesamte auszuführende Kommando muss von ihnen umschlossen sein.
trap löschen
Um einen trap wieder aufzuheben, kannst du
trap - exitverwenden. Dies ist nützlich, wenn du nur zwischenzeitlich auf ein Signal reagieren musst.
Fazit
Um beim Programmabbruch sauber aufzuräumen, kann dein Script auf Signale mit dem trap Kommando reagieren. In der Wikipedia gibt es eine Liste, die noch mehr Signale erklärt