Signale sind Software-Interrupts, die an ein Programm gesendet werden, um anzuzeigen, dass ein wichtiges Ereignis aufgetreten ist. Die Ereignisse können von Benutzeranforderungen bis zu unzulässigen Speicherzugriffsfehlern variieren. Einige Signale, wie z. B. das Interrupt-Signal, zeigen an, dass ein Benutzer das Programm aufgefordert hat, etwas zu tun, das nicht im üblichen Steuerungsfluss liegt.

Signale zur Prozesskontrolle durch den „normalen“ Benutzer

Nr.NameAktionBemerkung
1SIGHUPEndeTrennen der Terminalverbindung, siehe auch Terminal schließen.
2SIGINTEndeUnterbrechen der Terminalverbindung, siehe auch Strg+C.
3SIGQUITDump & EndeUnterbrechen der Terminalverbindung und debuggen.
9SIGKILLDump & EndeSenden Abbruch und debuggen durch den Kernel, siehe auch Wichtig.
14SIGALRMInternAlarm Signal. (Timers)
15SIGTERMEndeStandard bei allen kill-Programmen: Abschließen und beenden des Programms.

Eine vollständige Liste bekommt man mit dem Befehl:

 $ kill -l

Senden von Signalen

Es gibt verschiedene Methoden, um Signale an ein Programm oder Skript zu senden. Eine der häufigsten ist, dass ein Benutzer CONTROL-C eingibt, während ein Skript ausgeführt wird. Wenn Sie Strg + C drücken, wird ein SIGINT an das Skript gesendet und gemäß dem definierten Standardaktionsskript beendet. Die andere übliche Methode zur Übermittlung von Signalen ist die Verwendung des Befehls kill, dessen Syntax wie folgt lautet:

$ kill -signal pid

Der erste Befehlt schickt ein SIGHUP an den Prozess mit der Nummer 1234.
Der zweite Befehlt schickt ein Kill an den Prozess.

$ kill -1 1234
$ kill -SIGKILL 1234

Abfangen eines Signals

Um ein Signal abzufangen, das an Ihren Prozess gesendet wird, verwenden Sie den integrierten Trap-Befehl. Wenn ein Signal abgefangen wird, versucht der aktuell ausgeführte Befehl, den Prozess zu beenden, bevor der Trap-Befehl übernommen wird. Wenn es sich um ein SIGKILL-Signal handelt, wird der Prozess sofort beendet. Wenn Sie bestimmte Signale ignorieren, wird immer die Standardaktion ausgeführt. Wenn Sie z. B. nur auf SIGINT horchen, aber nichts gegen SIGQUIT unternehmen, dann findet, wenn Ihr Prozess ein SIGQUIT erhält, die Standardaktion statt (vermutlich ein unordentliches Beenden Ihres Skripts, was Sie wahrscheinlich nicht wollen).

Sehen wir uns nun ein einfaches Skript an, das SIGINT und SIGQUIT abfängt. Das Skript unten ist ein einfaches Zählerskript. Wenn der Benutzer Strg-C drückt, fängt der Trap-Befehl das Signal ab und gibt eine Meldung aus, dass das Skript beendet wurde. Die Beendigung erfolgt durch die Verwendung des Befehls exit am Ende der Befehlsliste. Wenn dies nicht geschieht, wird das Skript nicht beendet und setzt die Verarbeitung fort. In diesem Beispiel wollen wir, dass es beendet wird. Es kann vorkommen, dass dies nicht der Fall ist und die Verarbeitung fortgesetzt werden soll.

#!/bin/bash

trap 'echo Sie haben Ctrl-C gedrückt, das Skript wird jetzt beendet; exit' SIGINT SIGQUIT
counter=0

while :
 do
   sleep 1
   counter=$(expr $counter + 1)
   echo $counter
 done

Wie wird trap in der Praxis häufig verwendet? Immer wenn z.B. in einem Skript temporäre Dateien anlegt werden, sollten diese unbedingt am Ende aufgeräumt werden. Wird das Skript aus welchen Gründen auch immer unterbrochen, würden ohne den trap-Befehl die Dateien überbleiben. Mit trap kann man diese Dateien noch ordnungsgemäß zusammenräumen. Folgendes Skript verdeutlicht das.


trap 'exithandler' SIGINT

exithandler() {
   echo "Das Script wurde vorzeitig mit exit beendet!"
   # Hier noch anfallende Aufräumarbeiten ausführen
   rm -rf /tmp/mytemp
   exit
}


#Meine Hauptfunktion
touch /tmp/mytemp
echo "In der Hauptfunktion"
sleep 20

Weitere Details und Beispiele finden sich hier:

https://openbook.rheinwerk-verlag.de/shell_programmierung/shell_009_002.htm

https://developer.ibm.com/articles/au-usingtraps/

Image by Clker-Free-Vector-Images from Pixabay

Kategorien: DachsbergHowTo

0 Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.