Ostatnio natknąłem się na to w skrypcie powłoki.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
Co ma kill -0 ...
zrobić?
kill -0 $pid
skrypt powłoki? oraz Co właściwie robi kill 0? .
Ostatnio natknąłem się na to w skrypcie powłoki.
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
Co ma kill -0 ...
zrobić?
kill -0 $pid
skrypt powłoki? oraz Co właściwie robi kill 0? .
Odpowiedzi:
Ten jest trochę trudny do zdobycia, ale jeśli spojrzysz na następujące 2 strony podręcznika, zobaczysz następujące uwagi:
kill (1)$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
zabij (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.
...
Zatem sygnał 0 w rzeczywistości nie wyśle niczego do PID twojego procesu, ale sprawdzi, czy masz do tego uprawnienia.
Jednym oczywistym miejscem byłoby, gdybyś próbował ustalić, czy masz uprawnienia do wysyłania sygnałów przez uruchomiony proces kill
. Możesz sprawdzić przed wysłaniem właściwego kill
sygnału, owijając czek, aby upewnić się, że kill -0 <PID>
był on najpierw dozwolony.
Załóżmy, że proces był uruchamiany przez użytkownika root w następujący sposób:
$ sudo sleep 2500 &
[1] 15693
Teraz w innym oknie, jeśli uruchomimy to polecenie, możemy potwierdzić, że działa PID.
$ pgrep sleep
15693
Spróbujmy teraz tego polecenia, aby sprawdzić, czy mamy dostęp do wysyłania sygnałów PID za pośrednictwem kill
.
$ if ! kill -0 $(pgrep sleep); then echo "You're weak!"; fi
bash: kill: (15693) - Operation not permitted
You're weak!
Więc to działa, ale wynik przecieka komunikat z kill
polecenia, że nie mamy uprawnień. Nic wielkiego, po prostu złap STDERR i wyślij go na adres /dev/null
.
$ if ! kill -0 $(pgrep sleep) 2>/dev/null; then echo "You're weak!"; fi
You're weak!
Więc moglibyśmy zrobić coś takiego 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
Teraz, gdy uruchomię powyższe jako użytkownik inny niż root:
$ ~/killer.bash
you don't have permissions to kill PID:15693
$ echo $?
1
Jednak gdy jest uruchamiany jako root:
$ sudo ~/killer.bash
$ echo $?
0
$ pgrep sleep
$
pgrep
, ps
parsować ani test -e /proc/$PID
w przenośnych skryptach, ale kill -0
działa wszędzie. Jeśli otrzymasz identyfikator PID, który może być nieaktualny - np. /var/run
Wpis - jest to przenośny sposób sprawdzenia, czy proces nadal trwa.
kill -0 $(pgrep sleep)
może niekoniecznie oznaczać , że jesteś słaby , zwróci fałsz, jeśli nie sleep
uruchomi się żadna komenda, lub jeśli jest więcej niż jedna i jest jedna, której nie możesz zabić, lub jeśli jeden ze snów umrze między pgrep a zabiciem uruchamiane polecenia.
kill -0
(lub jego bardziej przenośny wariant POSIX kill -s 0
) przechodzi przez proces wysyłania sygnału, ale tak naprawdę go nie wysyła. Jest to funkcja bazowego C API, którą polecenie powłoki ujawnia w prosty sposób.
kill -s 0 -- "$pid"
testuje zatem, czy istnieje uruchomiony proces z danym PID (lub PGID, jeśli $pid
jest ujemny) i czy bieżący proces będzie miał pozwolenie na wysłanie (dowolnego z procesów w grupie procesów w przypadku ujemnej $pid
) sygnału. Jest to głównie sposób na sprawdzenie, czy proces (lub grupa procesów) żyje.
Należy pamiętać, że nawet jeśli jest uruchomiony proces z oczekiwanym PID i uprawnieniami, niekoniecznie jest to oczekiwany proces. Możliwe, że proces, którego się spodziewasz, umarł wcześniej, a jego PID został ponownie wykorzystany do niezwiązanego procesu. Właściwy sposób monitorowania procesów polega na tym, że pozwala to ich rodzicowi - PID procesu nie jest ponownie wykorzystywany, dopóki jego rodzic nie potwierdzi śmierci (dlatego istnieją zombie ), więc rodzic procesu może niezawodnie zidentyfikować swoje dzieci na podstawie ich PID.
kill -0 $pid
Informuje, czy z procesem $pid
istnieje.
We fragmencie
if ! kill -0 $(cat /path/to/file.pid); then
... do something ...
fi
blok ... do something ...
jest wykonywany, jeśli proces z przechowywanym PID /path/to/file.pid
jest uruchomiony - i - o ile fragment kodu nie działa jako root - jeśli PID działa z tym samym użytkownikiem.
Standard POSIX określa rolę 0
sygnału:
Jeśli sig wynosi 0 (sygnał zerowy), sprawdzanie błędów jest wykonywane, ale w rzeczywistości żaden sygnał nie jest wysyłany. Sygnał zerowy może być użyty do sprawdzenia ważności pid.
(kill (3p), POSIX.1-2008 - podobne sformułowanie w POSIX.1-2001)
Zauważ, że POSIX określa oba style kill -0
i kill -s 0
style wiersza poleceń (kill (1p)).
W przeciwieństwie do interfejsu kill syscall, kill
polecenia nie można użyć do wiarygodnego sprawdzenia istnienia PIDów należących do innych użytkowników (jako zwykły użytkownik), np .:
$ kill -0 123
kill: kill 123 failed: no such process
$ echo $?
1
vs.
$ kill -0 1
kill: kill 1 failed: operation not permitted
$ echo $?
1
Podczas wywoływania funkcji kill syscall można niezawodnie rozróżnić te przypadki, patrząc na errno
wartość (por. Np. Przykład w języku Python ).
trap
poleceniem Basha a 0 w stosunku do sygnału 0 zkill
: Co to jest sygnał 0 w poleceniu pułapki?