Was ein Signal ist
Ein Signal ist eine Ein-Wort-Nachricht, die der Kernel an einen Prozess zustellt: „das Terminal wurde geschlossen“, „du hast ungültigen Speicher berührt“, „bitte anhalten“. Der Prozess kann für die meisten einen Handler installieren, sie ignorieren oder die Standardaktion akzeptieren, die meist Beenden ist (manchmal mit Core-Dump). Zwei lassen sich weder abfangen noch ignorieren: SIGKILL beendet den Prozess sofort, und SIGSTOP friert ihn ein.
TERM gegen KILL
kill PID sendet SIGTERM: eine Bitte. Ein gut geschriebenes Programm fängt es ab, beendet die aktuelle Anfrage, schreibt Dateien, schließt Verbindungen und beendet sich; das senden systemd, Docker und Kubernetes zuerst. kill -9 sendet SIGKILL: Der Kernel entfernt den Prozess, ohne dessen Code auszuführen, also bleiben Locks gehalten, temporäre Dateien liegen, und laufende Schreibvorgänge gehen verloren. Nutzen Sie es nur, nachdem TERM Zeit hatte (systemd wartet TimeoutStopSec, Docker standardmäßig 10 Sekunden) und gescheitert ist.
Signale als API
- SIGHUP: Daemons laden ihre Konfiguration neu (nginx, sshd, HAProxy mit
-sf-Semantik über systemd reload). Für einen Vordergrundprozess heißt es, das Terminal ist weg;nohupignoriert es. - SIGUSR1 / SIGUSR2: programmdefiniert. nginx öffnet Logs bei USR1 neu und aktualisiert sein Binary bei USR2;
ddgibt bei USR1 den Fortschritt aus; Gunicorn und Unicorn nutzen sie für sanfte Neustarts. - SIGPIPE: Schreiben in eine Pipe, deren Leser beendet ist. Seine Standardaktion, Beenden, ist der Grund, warum
yes | headendet und warum Server es ignorieren oder Schreibfehler behandeln müssen. - SIGCHLD: Ein Kindprozess ist beendet; Eltern räumen Kinder mit
wait()ab, und ein Elternprozess, der das nicht tut, hinterlässt Zombies. - SIGWINCH: Das Terminal wurde in der Größe geändert; Editoren und Multiplexer zeichnen neu.
Signale senden
kill -TERM 1234 # per Name (oder kill -15 1234)
kill -s USR1 $(pidof nginx)
pkill -HUP sshd # per Prozessname
killall -9 runaway # alle Prozesse mit diesem Namen
systemctl kill -s HUP myservice
docker kill --signal=SIGUSR1 container Die Nummern 1–15 sind auf jedem Unix gleich; darüber unterscheiden sie sich nach Architektur (SIGUSR1 ist 10 auf x86 und 30 auf SPARC/MIPS), weshalb Skripte Namen verwenden sollten.
Fragen
Was ist der Unterschied zwischen SIGTERM und SIGKILL?
SIGTERM bittet den Prozess, sich zu beenden, und kann behandelt werden; SIGKILL beendet ihn sofort und lässt sich nicht abfangen. Versuchen Sie immer zuerst TERM; KILL ist für festhängende Prozesse.
Was ist Signal 11 / SIGSEGV?
Ein Segmentation Fault: Das Programm hat Speicher gelesen oder geschrieben, der ihm nicht gehört, meist ein Null- oder hängender Zeiger in C/C++-Code oder ein Fehler in einer nativen Erweiterung. Die Shell meldet Exit-Code 139.
Warum endete mein Prozess mit 137, obwohl niemand kill -9 ausgeführt hat?
Der Kernel hat es getan: Der Out-of-Memory-Killer sendet SIGKILL an den größten Prozess, wenn der Speicher ausgeht, und Container-Laufzeiten tun dasselbe, wenn ein Speicherlimit erreicht ist. Prüfen Sie dmesg oder das OOMKilled-Flag des Containers.
Kann ich SIGINT ignorieren, damit Strg-C mein Skript nicht stoppt?
Ja: trap "" INT in bash oder signal.signal(SIGINT, SIG_IGN) in Python. Meist ist es besser, es abzufangen und vor dem Beenden aufzuräumen, damit der Benutzer das Skript trotzdem stoppen kann.