kill (Unix)

kill (engl. töten) ist ein Unix-Kommando und gleichnamiger Systemaufruf, um unter dem Betriebssystem laufenden Prozessen Signale zu schicken. Standardmäßig wird bei dem UNIX-Kommando kill das Signal SIGTERM versendet, welches den entsprechenden Prozess dazu auffordert, sich zu beenden. Da das Beenden von Prozessen nur ein Anwendungsfall des Programms kill bzw. Systemaufrufes kill() ist, ist die Bezeichnung kill irreführend, da es sich allgemeiner um Interprozesskommunikation handelt. Der Name stammt von Unix-Versionen vor Unix-V4, bei denen es noch keinen Signal-Parameter gab.

Funktionsweise

Der Unix-Befehl kill stellt einen Wrapper um den Betriebssystemaufruf kill() dar. Zwar ist es auf jedem Unix-Derivat als alleinstehende Anwendung vorhanden (üblicherweise unter /bin/kill), alle modernen Unix-Shells verfügen allerdings – aufgrund seiner trivialen Implementierung – über ein eingebautes kill-Kommando.

Mit kill können viele verschiedene Signale versendet werden,[1] die am meisten benutzten Signale sind allerdings SIGTERM und SIGKILL. Ohne Angabe von Parametern versendet kill SIGTERM. Die empfangenden Programme können dieses Signal abfangen und vor dem Beenden noch unbedingt notwendige Arbeitsschritte durchführen, z. B. geöffnete Dateien abspeichern. SIGKILL wird verwendet, um einen Prozess, der sich trotz Empfang eines SIGTERM-Signals nicht beendet, zu beenden. SIGKILL kann, wie auch SIGSTOP, vom Programm nicht zur Durchzuführung programmspezifischer Aktionen „abgefangen“ werden. Die zwei Signale SIGKILL und SIGSTOP werden demnach nur vom Kernel „gesehen“ und bieten damit in jedem Fall zuverlässige Wege, einen Prozess zu kontrollieren. Während SIGKILL den Kernel anweist, den Prozess zu „töten“ (zu beenden), pausiert der Kernel den Prozess bei einem SIGSTOP, bis das Signal SIGCONT empfangen wird.

Nicht jeder Aufruf von kill dient dazu, einen Prozess zu beenden. So gibt z. B. das Programm dd bei dem Signal SIGUSR1 den aktuellen Verarbeitungsstatus eines Kopiervorgangs auf der Standardfehlerausgabe aus, dies lässt sich mit kill -USR1 $pid provozieren.

Bei Unix als klassischem Mehrbenutzersystem hat jeder Prozess einen Inhaber (UID). Jeder Prozess darf nur ein Signal zu einem Prozess, der dem gleichen Inhaber gehört, versenden. Das heißt, dass jeder Benutzer auch nur seine eigenen Prozesse beenden darf. Ausgenommen ist der Superuser, welcher jedem Prozess auf dem System Signale schicken darf.

Verwendung

Der Syntax des Unix-Befehls lautet

kill Parameter eine oder mehrere Prozess-IDs

als optionaler Parameter kann das gewünschte Signal angegeben werden, in der Form -SIGNAL, wobei SIGNAL entweder der Signalnummer oder dem Namen entspricht.

Um beispielsweise einem fiktiven Prozess mit der ID 4711 das Signal SIGTERM zu schicken, gibt es drei mögliche Aufrufvarianten:

  • kill 4711
  • kill -TERM 4711
  • kill -15 4711

Analog geschieht der Aufruf mit anderen Signalen, z. B. SIGKILL:

  • kill -KILL 4711
  • kill -9 4711

Ein Signal kann an alle Prozesse einer Prozessgruppe geschickt werden. Dazu wird die PID des „Gruppenleiters“ mit negativen Vorzeichen genommen (die PGID kann mit dem Programmaufruf ps -j ermittelt werden):

  • kill -CONT -4711

Alternativen

Tastenkombinationen

Die bei Unix üblichen Gerätetreiber verschicken Signale, wenn sie bestimmte Zeichen empfangen haben. Der Gerätetreiber kann mit dem Programm stty eingestellt werden.[2] Bei Unix-Shells mit Job-Control werden die Signale an die im Vordergrund laufende Prozessgruppe weiter gegeben. Um ein Programm zu beenden, reicht unter Unix so meist die Eingabe von Strg+C, um das Signal SIGINT auszulösen. Üblicherweise wird durch die Eingabe von Strg+Z SIGTSTP versandt, ferner mit Strg+\ SIGQUIT, welches den Kernel auffordert, einen Speicherauszug (core dump) auszugeben. Die maximale Größe eines Speicherauszugs kann eingestellt werden und kann den Wert 0 (kein Speicherauszug erstellen) annehmen.[3]

killall

Einige Unix-Derivate, unter anderem Solaris, rufen das Unix-Kommando killall automatisch auf, wenn das System herunterfährt. Es verhält sich wie kill, nur wird ein Signal nicht nur zu einem einzigen Prozess geschickt, sondern zu allen Prozessen auf dem System.

Auf anderen Unix-Derivaten, u. a. IRIX, Linux und FreeBSD, wird das Kommando killall hingegen verwendet, um einen Prozess anhand seines Namens zu beenden. Um zum Beispiel XMMS, einen Mediaplayer, der per xmms aufgerufen wurde, zu beenden, gibt der Benutzer killall xmms ein. Auf diese Weise werden alle Prozesse mit dem Namen xmms beendet. Zudem existiert üblicherweise zusätzlich killall5, das sich ähnlich wie das killall von SystemV/Solaris verhält.

pkill

pkill beendet Prozesse anhand von Teilen ihres Namens. Das Kommando wurde in Solaris 7 eingeführt und wurde seitdem auch in Linux und OpenBSD implementiert. pkill ermöglicht es, Prozesse anhand ihres Namens einfacher zu beenden, als es mit killall möglich ist, wenn man deren genauen Namen nicht kennt.

Um zum Beispiel die dem Webbrowser Firefox zugehörigen Prozesse zu beenden, ohne sich dabei pkill sowie pgrep zu bedienen, müsste man eine Zeile wie kill $(ps ax | awk '$5~/firefox/{print $1}') schreiben, wohingegen mit pkill bereits die Eingabe von pkill firefox den Zweck erfüllt.

Siehe auch

  • xkill, zum Beenden von X-Window-Programmen

Einzelnachweise

  1. siehe Signal (Unix) für eine Liste der üblichen Signale
  2. https://www.man7.org/linux/man-pages/man1/stty.1.html
  3. https://manpages.ubuntu.com/manpages/trusty/man2/setrlimit.2.html

Weblinks