Öldür -0 ne yapar?


61

Geçenlerde bir kabuk komut dosyasında bu karşılaştı.

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

Ne yapar kill -0 ...?


2
S / b Bash'in trapkomutu ile 0 ile 0 arasındaki bir sinyalle 0 arasındaki farklar konusunda kafanız karıştıysa, buraya bakın kill: Tuzak komutunda sinyal 0 nedir?
slm

Yanıtlar:


76

Bunu yapmak biraz zordur, ancak aşağıdaki 2 kılavuz sayfasına bakarsanız aşağıdaki notları göreceksiniz:

öldürmek (1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
öldürmek (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.
...

Bu nedenle, sinyal 0 aslında işleminizin PID'sine hiçbir şey göndermez, ancak izinleriniz olup olmadığını kontrol eder.

Bu nerede faydalı olabilir?

Bariz bir yer, üzerinden çalışan bir işleme sinyal gönderme izniniz olup olmadığını belirlemeye çalışıyor olmanızdı kill. İstediğiniz gerçek killsinyali göndermeden önce kill -0 <PID>, ilk izin verildiğinden emin olmak için bir çek kaydı yaparak kontrol edebilirsiniz .

Örnek

Bir işlemin aşağıdaki gibi kök tarafından çalıştırıldığını söyleyin:

$ sudo sleep 2500 &
[1] 15693

Şimdi bu komutu çalıştırırsak başka bir pencerede PID'nin çalıştığını doğrulayabiliriz.

$ pgrep sleep
15693

Şimdi bu komutu PID sinyallerini göndermeye erişimimiz olup olmadığını görmek için deneyelim kill.

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

Bu yüzden işe yarıyor, ancak çıktı killkomuttan izin almamamızın bir mesajını sızdırıyor . Önemli bir şey değil, STDERR'i yakalayın ve gönderin /dev/null.

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

Tam bir örnek

O zaman şöyle bir şey yapabiliriz 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

Şimdi yukarıdakileri root olmayan bir kullanıcı olarak çalıştırdığımda:

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

$ echo $?
1

Ancak root olarak çalıştırıldığında:

$ sudo ~/killer.bash 

$ echo $?
0

$ pgrep sleep
$

9
Ayrıca, bir sürecin hala devam edip etmediğini görmek için çok aşamalı komut dosyaları için kullanılabileceğini de eklerdim.
prateek61

1
@slm nice find. Bu mantığı şu anda bir komut dosyasında kullanıyorum, teşekkürler.
111 ---

12
Prateek61 haklı. Sen kullanamaz pgrep, psayrıştırma veya test -e /proc/$PIDtaşınabilir scrips içinde, ama kill -0her yerde çalışır. Bayat olabilecek bir PID verilirse - örneğin bir /var/rungiriş - bu işlemin hala hayatta olup olmadığını kontrol etmenin taşınabilir yoludur.
Warren Young

1
PID'nin canlı olup olmadığını söylemenin yanı sıra, diğer UID'lere sinyal gönderme izniniz olmadığından (root olmadığınız sürece), hala UID'nizden bir işlem yürütüp yürütmediğini de etkili bir şekilde söyler. Bu, PID'nin yeniden kullanımı nedeniyle yanlış pozitifleri daha az olası kılar.
Barmar

Bir başarısızlık kill -0 $(pgrep sleep), mutlaka zayıf olduğunuz anlamına gelmeyebilir , herhangi bir sleepkomut çalıştırılmazsa veya birden fazla tane varsa ve öldüremeyeceğiniz bir kişi varsa veya uyuyanlardan biri pgrep ile öldürme arasında ölürse yanlış dönecektir. komutları çalıştırılıyor.
Stéphane Chazelas 27:14

22

kill -0(veya daha taşınabilir POSIX varyantı kill -s 0) bir sinyal gönderme hareketinden geçer, ancak bir tane göndermez. Bu bir özelliği var altında yatan C API kabuk komutu basit bir şekilde ortaya çıkarır.

kill -s 0 -- "$pid"bu nedenle, verilen PID ile çalışan bir işlem olup olmadığını (veya negatifse PGID $pid) ve mevcut işlemin (bir negatif durumda işlem grubundaki işlemlerden herhangi biri $pid) bir sinyal gönderme izninin olup olmadığını test eder . Çoğunlukla bir sürecin (veya işlem grubunun) canlı olup olmadığını test etmenin bir yolu.

Beklenen PID ve izinleri ile çalışan bir işlem olsa bile, bu mutlaka beklediğiniz bir işlem değildir. Beklediğiniz sürecin daha önce ölmüş olması ve PID'sinin alakasız bir işlem için yeniden kullanılması muhtemeldir. İşlemleri izlemenin doğru yolu, ebeveynlerinin bunu yapmasına izin vermektir - bir işlemin PID'si, ebeveyninin ölümünü kabul edinceye kadar tekrar kullanılmaz (bu yüzden zombiler var), böylece bir işlemin ebeveyni, çocuklarını güvenilir bir şekilde PID'leri ile tanımlayabilir.


0

kill -0 $pidBir süreç ile eğer size söyler $pidbulunmaktadır.

Snippet'te

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

PID aynı kullanıcının altında çalışıyorsa ... do something ..., depoda saklanan PID ile bir işlem /path/to/file.pidçalışıyorsa - ve - snippet root olarak çalışmadığı sürece - blok çalıştırılır .

POSIX standardı 0sinyalin rolünü belirtir :

Sig 0 ise (boş sinyal), hata kontrolü yapılır, ancak sinyal gönderilmez. Boş sinyal, ödemenin geçerliliğini kontrol etmek için kullanılabilir.

(öldürme (3p), POSIX.1-2008 - POSIX.1-2001’deki benzer ifadeler)

POSIX’in her ikisini kill -0ve kill -s 0komut satırı stillerini belirttiğine dikkat edin (kill (1p)).

Kill syscall arabiriminin aksine, killkomut, diğer kullanıcıların sahip olduğu PID'lerin (normal bir kullanıcı olarak) varlığını güvenilir bir şekilde kontrol etmek için kullanılamaz, örneğin:

$ 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

Öldürme sistemi çağrıldığında kişi bu durumları errnodeğere bakarak güvenilir bir şekilde ayırt edebilir (bkz. Örneğin bir Python Örneği ).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.