5.3    Das kill-Kommando und Signale

Zur Steuerung von Prozessen werden unter Unix sogenannte Signale verwendet. Ein Signal können Sie sich als Steueranweisung in Form einer Zahl vorstellen. Solch ein Signal wird entweder durch einen Prozess im Userspace oder direkt vom Kernel an einen Prozess gesendet. (Letztendlich sendet immer der Kernel und kein Prozess solch ein Signal. Ein Kommando wie kill fordert den Kernel lediglich auf, ein Signal zu senden.)

Softinterrupts

Signale werden oft auch als Softinterrupts bezeichnet.

Es gibt verschiedene Signale. So kann zum Beispiel ein Prozess zur Terminierung über das Signal 9 (SIGKILL) gezwungen werden. Terminator! Es gibt allerdings auch Signale, die vom Prozess abgefangen werden können. Ob ein Prozess auf ein solches Signal reagiert und welche Aktionen genau er dann durchführt, liegt ganz allein im Ermessen des Programmierers.

Dem Benutzer bzw. der Benutzerin steht mit dem Kommando kill die Möglichkeit zur Verfügung, Signale zu versenden. Hierbei werden der Signaltyp und die Prozess-ID des Zielprozesses bzw. dessen Jobnummer angegeben.

$ kill 499
$ kill -9 500
$ kill -SIGKILL 501

Listing 5.16     Beispielaufruf des kill-Kommandos

SIGTERM als Standardeinstellung

Wird kill ohne einen Signalparameter und lediglich mit einer Prozess-ID aufgerufen, so wird das Signal SIGTERM an den Prozess gesendet, das ihn zur Beendigung auffordert, aber nicht zwingend seine Beendigung erwirkt.

5.3.1    Welche Signale gibt es?

Wie wir bereits erwähnt haben, gibt es zwei Gruppen von Signalen: Eine Gruppe kann vom Prozess ignoriert werden, die andere nicht.

Es gibt zwei Signale, die den Prozess zwingen, sich dem Signal zu beugen (besser gesagt: die den Kernel veranlassen, den Prozess zu beenden oder zu stoppen):

Die anderen Signale (es gibt ca. 30 Signale) werden teilweise so gut wie niemals vom Anwender benötigt. Daher stellen wir an dieser Stelle nur die für den Anwender und den Administrator bzw. die Administratorin wichtigsten und nützlichen Signale vor:

Einige Shells (wie z. B. die bash) enthalten ihre eigenen Implementierungen des kill-Kommandos. Diese Implementierungen bieten vereinzelt weitere Signaltypen. Die bash zum Beispiel unterstützt über 60 verschiedene Signale. Hierbei sollte zwischen den shellinternen Kommandos und Programmen unterschieden werden.

Eine Liste der von Ihrem kill unterstützten Signale bekommen Sie durch einen Aufruf von kill -l. Das Linux-kill-Kommando kennt darüber hinaus den -L-Parameter für eine tabellarische Ausgabe.

5.3.2    Beispiel: Anhalten und Fortsetzen eines Prozesses

Zur Verdeutlichung folgt nun ein Anwendungsbeispiel. Unser Ziel ist es, einen Prozess mit hohem Rechenaufwand zu starten. Er soll jedoch angehalten werden, um einige andere Prozesse ohne Verzögerung starten zu können. Nachdem die Nutzung der anderen Prozesse abgeschlossen ist, soll der Prozess fortgesetzt werden.

Unser »Rechenleistungskiller« wird in diesem Fall das find-Kommando sein, mit dem das gesamte Dateisystem nach Vorkommen des Dateinamens »group« durchsucht wird. In der Zwischenzeit soll allerdings ein anderes Programm ausgeführt werden. In Abschnitt 5.4.1 lernen Sie übrigens eine weitere Methode zur Lösung dieses Problems kennen, indem wir die Priorität eines Prozesses verringern.

$ find / -name group >erg.txt 2>/dev/null &
[1] 628
$ kill -STOP 628
[1]+ Stopped find / -name group >erg.txt 2>/dev/null
(es vergeht etwas Zeit)
$ jobs
[1]+ Stopped find / -name group >erg.txt 2>/dev/null
$ kill -CONT %1
$ wait %1
[1]+ Exit 1  find / -name group >erg.txt 2>/dev/null
$ cat erg.txt
/etc/X11/xkb/symbols/group
/etc/group

Listing 5.17     Anwendung des kill-Kommandos mit STOP und CONT

Wie Sie sehen, ist bei Hintergrundprozessen sowohl die Angabe der Prozess-ID als auch die der Hintergrundprozessnummer möglich. Statt des Aufrufs kill -STOP 628 hätte genauso das Kommando kill -STOP %1 »nach Rom geführt«. Natürlich könnte anstelle des -STOP-Parameters auch -SIGSTOP oder -19 stehen.

killall

Das Kommando killall funktioniert ähnlich wie kill, beendet Prozesse jedoch über ihren Namen.

// Ein Benutzer startet auf einem Terminal 'find' …
$ find / -name lib

// … währenddessen in einem anderen Terminal …
# killall find

// … der Benutzer erfährt schließlich von der Beendigung:
Terminated

Listing 5.18     Ein Beispiel für killall