Apa yang dilakukan `kill -0 $ pid` dalam skrip shell?

Jawaban:

136

mengirim sinyal 0ke yang diberikan PIDhanya memeriksa apakah proses dengan yang diberikan PIDsedang berjalan dan Anda memiliki izin untuk mengirim sinyal ke sana.

Untuk informasi lebih lanjut lihat halaman manual berikut:

bunuh (1)
$ man 1 kill
...
If sig is 0, then no signal is sent, but error checking is still performed.
...
bunuh (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.
...
dwalter
sumber
7
Lokasi informasi ini (jika ada sama sekali) sangat bergantung pada sistem. Pada sistem berbasis Debian baru-baru ini, gunakan man 2 killsaja.
Todd A. Jacobs
2
Keduanya man 1 killdan man 2 killmemilikinya di sistem Fedora 20 saya. Sulit dikenali, terkubur di kedua halaman manual itu.
slm
Atau andalkan manual If sig is 0 (the null signal), error checking is performed but no signal is actually sent. The null signal can be used to check the validity of pid. posix
Thomas Hughes
2
Saya merasa seperti perintah di man 2 killluar amandemen ke-1 :)
JBaczuk
126

Ini Pertanyaan Yang Bagus Karena ...

... sulit menemukan dokumentasi tentang sinyal khusus ini. Terlepas dari apa yang dikatakan orang lain, satu-satunya penyebutan sinyal ini dalam man 1 killsistem berbasis Debian adalah:

Sinyal yang sangat berguna termasuk HUP, INT, KILL, STOP, CONT, dan 0.

Tidak terlalu membantu, terutama jika Anda belum tahu apa yang dilakukan sinyal. Ini juga tidak terdaftar oleh output dari kill -l, jadi Anda tidak akan mengetahuinya kecuali Anda sudah mengetahuinya.

Di mana Menemukannya Didokumentasikan

Pada sistem Debian dan Ubuntu, output dari man 2 kill kata, sebagian:

Jika sig adalah 0, maka tidak ada sinyal yang dikirim, tetapi pengecekan kesalahan masih dilakukan; ini dapat digunakan untuk memeriksa keberadaan ID proses atau ID grup proses.

Untuk Apa Ini Baik?

Anda dapat menggunakan kill -0untuk memeriksa apakah suatu proses sedang berjalan. Pertimbangkan contoh-contoh ini.

# Kill the process if it exists and accepts signals from
# the current user.
sleep 60 &
pid=$!
kill -0 $pid && kill $pid

# Check if a PID exists. When missing, this should result
# in output similar to:
#    bash: kill: (6228) - No such process
#    Exit status: 1
kill -0 $pid; echo "Exit status: $?"

Anda juga dapat menggunakan kill -0untuk menentukan apakah pengguna saat ini memiliki izin untuk menandai proses yang diberikan. Sebagai contoh:

# See if you have permission to signal the process. If not,
# this should result in output similar to:
#     bash: kill: (15764) - Operation not permitted
#     Exit status: 1
sudo sleep 60 &
kill -0 $!; echo "Exit status: $?"
Todd A. Jacobs
sumber
Pada mac dan BSD, ini juga didokumentasikan dalam kill(2) cuplikan:The kill() function sends the signal specified by sig to pid, a process or a group of processes. Typically, Sig will be one of the signals specified in sigaction(2). A value of 0, however, will cause error checking to be performed (with no signal being sent). This can be used to check the validity of pid.
lukecampbell
8
Ini harus menjadi jawaban yang diterima. Jauh lebih baik dari yang lain. dokumentasi pada sinyal 0 sulit ditemukan. Itu terkubur di killhalaman manual: "Jika sig adalah 0, maka tidak ada sinyal yang dikirim, tetapi pengecekan kesalahan masih dilakukan."
slm
6

Perintah ini memeriksa apakah proses dengan PID dalam $ pid masih hidup.

Fritz G. Mehner
sumber
1
Halaman manual mengatakan: "Jika sig adalah 0, maka tidak ada sinyal yang dikirim, tetapi pengecekan kesalahan masih dilakukan." Pemeriksaan kesalahan apa yang kami maksudkan di sini?
gjain
2
-1, karena proses dengan PID $pidmungkin berjalan tetapi Anda tidak memiliki izin untuk mengirim sinyal kepadanya.
dwalter
2
@walter: Jika Anda tidak memiliki izin Anda akan mendapatkan EPERM. Jika tidak ada, Anda akan mendapatkan ESRCH. The kill(1)akan mencetak kesalahan yang berbeda untuk masing-masing. Jadi, Anda dapat mengetahui apakah pid masih hidup terlepas dari apakah Anda memiliki izin untuk mengirim sinyal atau tidak. Lebih jauh, penggunaan tipikal kill -0adalah untuk melihat apakah pid masih hidup, bahkan jika itu tidak selalu digunakan dengan benar. Saya akan mengatakan jawaban ini benar (terlepas dari ejaan).
camh
3
@camh: tidak ada nilai balik kill -0 $pidakan sama dalam kedua kasus. Ini akan kembali 1sehingga Anda tidak bisa mengatakan tanpa mem-parsing ouput killjika proses sedang berjalan atau tidak, jika Anda tidak memiliki izin untuk mengirim sinyal ke sana. EDIT: ya saya tahu itu digunakan sebagian besar waktu untuk memeriksa apakah suatu proses masih hidup, tetapi ini salah kecuali Anda dapat menjamin bahwa Anda memiliki izin untuk mengirim sinyal (misalnya: menjadi root)
dwalter
2
@walter: Maksud saya adalah jawabannya benar. Anda mencoba menjadi bertele-tele dan menunjukkan bahwa ada kasus kesalahan lain, tetapi saya mengatakan kepada Anda bahwa secara teknis jawabannya mencakup kasus itu juga karena killbash built-in (pertanyaannya ditandai bash) menghasilkan jenis kesalahan pada stderr, dan indikasi kesalahan dalam kode pengembaliannya. Yaitu, "Perintah ini memeriksa [apakah] proses dengan PID dalam $ pid masih hidup" sepenuhnya benar jika Anda mengartikan output dengan benar. [Saya tidak akan berkomentar jika Anda tidak mengatakan Anda memberi -1 pada jawabannya. Komentar Anda dinyatakan valid].
camh
6

Kill -0 $ pid adalah untuk memeriksa apakah proses dengan pid ada atau tidak.

Hati-hati saat menggunakan 'kill -0 $ pid' untuk memeriksa keberadaan proses karena

  1. Setelah proses yang dimaksud keluar maka pidnya dapat dibagi ke proses lain yang baru dibuat. (Jadi seseorang tidak bisa begitu yakin bahwa proses tertentu masih hidup atau tidak)

  2. Dalam kasus proses Zombie, anak yang menunggu orang tua untuk memanggil menunggu. Ini dia memegang $ pid dan memberikan hasil positif sementara proses itu tidak berjalan.

Sandeep_black
sumber
1

Bunuh -0 $ pid digunakan untuk memeriksa apakah proses yang berjalan dengan $ pid masih hidup atau tidak. Tapi ini bisa rumit, karena ID proses dapat dipindahkan, setelah proses keluar dan proses baru berjalan. Seseorang dapat menggunakan killall -0 untuk mendapatkan proses tertentu sedang berjalan atau tidak.


sumber
0

Mengirim EXITsinyal, atau 0ke suatu proses akan:

  1. Periksa keberadaan suatu proses.
  2. Lakukan berbagai pengecekan kesalahan pada proses (PID, PGID, dll ...).
  3. Ini tidak akan mengirim output apa pun ke stdout setelah berhasil.
  4. Kirim pesan kesalahan ke stderr jika ada sesuatu yang tidak benar.
  5. Memberi Anda false positive jika prosesnya mati (yaitu Zombie).

Secara lebih eksplisit, fungsi yang berguna untuk skrip shell Anda adalah:

function isProcess ()
{
    kill -s EXIT $1 2> /dev/null
}

Ini tidak mengembalikan teks pada stdoutsaat berhasil, tetapi pesan kesalahan menjadi stderrpada kegagalan (tapi saya telah mengarahkan pesan kesalahan itu ke/dev/null ).

Jika Anda khawatir tentang status proses zombie / mati , maka Anda perlu menggunakan ps, lebih disukai dengan --no-headerssaklar.

#!/bin/ksh

function trim ()
{
    echo -n "$1" | tr -d [:space:]
}

function getProcessStatus ()
{
    trim $(ps -p $1 -o stat --no-headers)
}

function isZombie ()
{
    typeset processStatus=$(getProcessStatus $1)

    [[ "$processStatus" == "Z" ]]
    return $?
}
Anthony Rutledge
sumber