Was macht 'kill -0'?

61

Ich bin kürzlich in einem Shell-Skript darauf gestoßen.

if ! kill -0 $(cat /path/to/file.pid); then
    ... do something ...
fi

Was macht kill -0 ...das?

slm
quelle
2
Sehen Sie hier, wenn Sie verwirrt sind über die Unterschiede zwischen dem trapBefehl " Bash" und "0" und einem Signal "0" von kill: Was ist das Signal "0" in einem Trap-Befehl?
slm
Siehe auch die ältere StackOverflow-Frage Was macht kill -0 $pidein Shell-Skript? sowie Was macht Kill 0 eigentlich? .
Adam Katz

Antworten:

76

Dieser ist etwas schwer zu finden, aber wenn Sie sich die folgenden 2 Manpages ansehen, werden Sie die folgenden Hinweise sehen:

töten (1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
töten (2)
$ man 2 kill
...
If sig is 0, then no signal is sent, but error checking is still performed; 
this can be used to check for the existence of a process ID or process 
group ID.
...

Das Signal 0 sendet also eigentlich nichts an die PID Ihres Prozesses, prüft jedoch, ob Sie dazu berechtigt sind.

Wo könnte das nützlich sein?

Ein offensichtlicher Ort wäre, wenn Sie versuchen würden, festzustellen, ob Sie die Berechtigung haben, Signale über an einen laufenden Prozess zu senden kill. Sie können überprüfen, bevor killSie das gewünschte Signal senden , indem Sie einen Scheck einwickeln, um sicherzustellen, dass dies kill -0 <PID>zuerst zulässig war.

Beispiel

Angenommen, ein Prozess wurde von root wie folgt ausgeführt:

$ sudo sleep 2500 &
[1] 15693

Wenn wir diesen Befehl jetzt in einem anderen Fenster ausführen, können wir bestätigen, dass diese PID ausgeführt wird.

$ pgrep sleep
15693

Versuchen wir nun diesen Befehl, um zu sehen, ob wir Zugriff haben, um diese PID-Signale über zu senden kill.

$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!

Es funktioniert also, aber die Ausgabe gibt eine Meldung aus dem killBefehl aus, dass wir keine Berechtigungen haben. Keine große Sache, fangen Sie einfach STDERR und senden Sie es an /dev/null.

$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!

Vollständiges Beispiel

Dann könnten wir so etwas machen killer.bash:

#!/bin/bash

PID=$(pgrep sleep)
if ! kill -0 $PID 2>/dev/null; then 
  echo "you don't have permissions to kill PID:$PID"
  exit 1
fi

kill -9 $PID

Jetzt, wenn ich das oben genannte als Nicht-Root-Benutzer ausführe:

$ ~/killer.bash 
you don't have permissions to kill PID:15693

$ echo $?
1

Wenn es jedoch als root ausgeführt wird:

$ sudo ~/killer.bash 

$ echo $?
0

$ pgrep sleep
$
slm
quelle
9
Ich würde auch hinzufügen, dass dies für Multi-Proc-Skripte verwendet werden könnte, um zu sehen, ob ein Prozess noch aktiv ist.
Prateek61
1
@slm schön zu finden. Ich benutze diese Logik gerade in einem Skript und schreibe, danke.
111 -
12
Prateek61 ist richtig. Sie können es nicht verwenden pgrep, psanalysieren oder test -e /proc/$PIDin tragbaren Skripten verwenden, es kill -0funktioniert jedoch überall. Wenn Sie eine PID erhalten, die möglicherweise veraltet ist, z. B. einen /var/runEintrag , können Sie auf einfache Weise überprüfen, ob der Prozess noch aktiv ist.
Warren Young
1
Sie werden nicht nur darüber informiert, ob die PID aktiv ist, sondern auch, ob von Ihrer UID aus noch ein Prozess ausgeführt wird, da Sie keine Berechtigung zum Senden von Signalen an andere UIDs haben (es sei denn, Sie sind Root). Dies verringert die Wahrscheinlichkeit von Fehlalarmen aufgrund von PID-Wiederverwendung.
Barmar
Ein Fehler musskill -0 $(pgrep sleep) nicht unbedingt bedeuten, dass Sie schwach sind. Er gibt false zurück, wenn kein sleepBefehl ausgeführt wird oder wenn mehr als einer ausgeführt wird und einer nicht getötet werden kann oder wenn einer der Schlafzustände zwischen dem pgrep und dem kill stirbt Befehle ausgeführt werden.
Stéphane Chazelas
22

kill -0(oder die tragbarere POSIX-Variante kill -s 0) sendet zwar ein Signal, sendet jedoch keines. Es ist eine Funktion der zugrunde liegenden C-API , die der Shell-Befehl auf einfache Weise verfügbar macht.

kill -s 0 -- "$pid"Somit wird geprüft, ob ein Prozess mit der angegebenen PID ausgeführt wird (oder ob PGID $pidnegativ ist) und ob der aktuelle Prozess die Berechtigung hat, ihm (bei einem negativen Prozess ein beliebiger Prozess in der Prozessgruppe $pid) ein Signal zu senden. Dies ist meistens eine Möglichkeit zu testen, ob ein Prozess (oder eine Prozessgruppe) aktiv ist.

Beachten Sie, dass dies nicht unbedingt der erwartete Prozess ist, auch wenn ein Prozess mit der erwarteten PID und den erwarteten Berechtigungen ausgeführt wird. Es ist möglich, dass der Prozess, von dem Sie erwarten, dass er früher gestorben ist und seine PID für einen nicht verwandten Prozess wiederverwendet wurde. Die richtige Methode zum Überwachen von Prozessen besteht darin, das übergeordnete Element dazu zu überlassen. Die PID eines Prozesses wird erst dann wiederverwendet, wenn das übergeordnete Element den Tod bestätigt hat (daher gibt es Zombies ). Daher kann das übergeordnete Element eines Prozesses seine untergeordneten Elemente zuverlässig anhand ihrer PID identifizieren.

Gilles 'SO - hör auf böse zu sein'
quelle
0

Das kill -0 $pidteilt Ihnen mit, ob ein Prozess mit $pidexistiert.

Im Ausschnitt

if ! kill -0 $(cat /path/to/file.pid); then
    ... do something ...
fi

Der Block ... do something ...wird ausgeführt, wenn ein Prozess mit der in gespeicherten PID ausgeführt /path/to/file.pidwird - und - sofern das Snippet nicht als Root ausgeführt wird - wenn die PID unter demselben Benutzer ausgeführt wird.

Der POSIX-Standard legt die Rolle des 0Signals fest:

Wenn sig 0 ist (das Nullsignal), wird eine Fehlerprüfung durchgeführt, es wird jedoch kein Signal gesendet. Das Nullsignal kann verwendet werden, um die Gültigkeit von pid zu überprüfen.

(kill (3p), POSIX.1-2008 - ähnlicher Wortlaut in POSIX.1-2001)

Beachten Sie, dass POSIX sowohl kill -0als auch kill -s 0Befehlszeilenstile angibt (kill (1p)).

Im Gegensatz zur kill syscall-Schnittstelle kann mit dem killBefehl nicht zuverlässig überprüft werden, ob PIDs anderer Benutzer (als normaler Benutzer) vorhanden sind, z.

$ kill -0 123
kill: kill 123 failed: no such process
$ echo $?
1

gegen

$ kill -0 1
kill: kill 1 failed: operation not permitted
$ echo $?
1

Beim Aufruf des kill syscall kann man diese Fälle anhand des errnoWertes zuverlässig unterscheiden (vgl. ZB ein Python-Beispiel ).

maxschlepzig
quelle