Saya sedang menulis skrip Perl yang mem-parsing file log untuk mengumpulkan PID dan kemudian memeriksa apakah PID itu berjalan. Saya mencoba memikirkan cara terbaik untuk melakukan pemeriksaan itu. Jelas, saya bisa melakukan sesuatu seperti:
system("ps $pid > /dev/null") && print "Not running\n";
Namun, saya lebih suka menghindari panggilan sistem jika memungkinkan. Karena itu saya pikir saya bisa menggunakan sistem /proc
file (portabilitas bukan masalah, ini akan selalu berjalan pada sistem Linux). Sebagai contoh:
if(! -d "/proc/$pid"){
print "Not running\n";
}
Apakah itu aman? Bisakah saya selalu berasumsi bahwa jika tidak ada /proc/$pid/
direktori PID terkait tidak berjalan? Saya berharap demikian karena AFAIK ps
sendiri mendapatkan informasinya /proc
tetapi karena ini untuk kode produksi, saya ingin memastikan.
Jadi, dapatkah ada kasus di mana proses yang berjalan tidak memiliki /proc/PID
direktori atau di mana /proc/PID
direktori ada dan proses tersebut tidak berjalan? Apakah ada alasan untuk lebih memilih parsing ps
daripada memeriksa keberadaan direktori?
sumber
kill
fungsi perl menggunakan sinyal 0 yang tidak membunuh tetapi mengatakan jika Anda bisa melakukannya (yaitu Anda perlu izin untuk memberi sinyal pada proses itu).kill -0
yang terbaik), ini hanya memberi tahu Anda apakah ada proses yang berjalan dengan PID yang diberikan . Itu tidak memberi tahu Anda apakah proses masih akan berjalan satu milidetik kemudian, dan tidak memberi tahu Anda apakah proses tersebut adalah yang Anda minati atau proses yang tidak terkait yang mendapat PID yang sama setelah proses yang menarik tersebut selesai . Hampir selalu merupakan kesalahan untuk menguji apakah suatu PID berjalan : ada sangat sedikit keadaan di mana ini tidak rentan terhadap kondisi balapan.Jawaban:
Fungsi perl
kill(0,$pid)
dapat digunakan.Jika kode pengembaliannya 1 maka PID ada dan Anda diizinkan mengirim sinyal kepadanya.
Jika kode pengembalian adalah 0 maka Anda perlu memeriksa $ !. Mungkin EPERM (izin ditolak) yang berarti proses itu ada atau ESRCH dalam hal mana proses itu tidak ada.
Jika kode pemeriksaan Anda berjalan
root
maka Anda dapat menyederhanakan ini hanya dengan memeriksa kode pengembalian kill; 0 => kesalahan, 1 => okSebagai contoh:
Ini dapat dibuat menjadi fungsi sederhana
sumber
if (!kill(0,$pid) && $! =~ /No such process/){ exit; }
atau serupa. Saya sukaErrno
solusi Anda lebih baik, terima kasih. Sementara saya mungkin akan pergi dengan ini, saya akan menunggu beberapa saat jika ada yang bisa menjawab pertanyaan Linux yang mendasarinya./proc
sudah terpasang maka setiap PID yang terlihat di namespace akan ada, jadi-d /proc/$pid
pengujian Anda akan berhasil ... tetapi melibatkan keluar ke sistem file daripada menggunakan panggilan sistem asli.system
panggilan" - yaitu, panggilan kesystem
fungsi itu sendiri, bukan "panggilan sistem" . Yang terakhir Anda tidak bisa menghindari, tetapi yang pertama Anda pasti bisa. Masuk akal sekarang!/proc/PID
kill 0
/proc
/proc
ps
top
lsof
), dan saya percaya bahwa tidak ada jaminan bahwa itu akan ada (yaitu, itu tidak diperlukan oleh POSIX). Dan, kecuali sistem itu sepenuhnya disemprot,kill
akan berfungsi./proc
memerlukan membaca direktori root untuk menemukan sistem/proc
file. Hal ini berlaku untuk setiap usaha untuk mengakses setiap file dengan nama path absolut, termasuk hal-hal di/bin
,/etc
, dan/dev
. Ini terjadi begitu sering sehingga direktori root pasti di-cache dalam memori untuk seumur hidup (uptime) sistem, sehingga langkah ini dapat dilakukan tanpa disk I / O. Dan, begitu Anda memiliki inode/proc
, semua hal lain yang terjadi adalah dalam memori./proc
? Denganstat
,open
,readdir
, dll, yang sistem asli panggilan setiap bit sebanyakkill
.Pertanyaannya berbicara tentang proses yang sedang berjalan. Ini adalah ungkapan yang licin. Jika Anda benar-benar ingin menguji apakah proses sedang berjalan (yaitu, dalam antrian proses; mungkin proses saat ini pada beberapa CPU; tidak tidur, menunggu, atau berhenti), Anda mungkin perlu melakukan dan membaca output , atau melihat . Tetapi saya tidak melihat petunjuk dalam pertanyaan atau komentar Anda bahwa Anda prihatin dengan ini.
ps PID
/proc/PID/stat
Gajah di ruangan itu, bagaimanapun, adalah bahwa proses zombie 2 bisa sulit dibedakan dari proses yang hidup dan sehat.
kill 0
bekerja pada zombie, dan ada. Anda dapat mengidentifikasi zombie dengan teknik yang tercantum dalam paragraf sebelumnya (melakukan dan membaca hasilnya, atau melihat ). Saya sangat cepat & santai (yaitu, tidak sangat teliti) pengujian menunjukkan bahwa Anda juga dapat melakukan ini dengan melakukan atau pada , atau - ini akan gagal pada zombie. (Namun, mereka juga akan gagal pada proses yang tidak Anda miliki.)/proc/PID
ps PID
/proc/PID/stat
readlink
lstat
/proc/PID/cwd
/proc/PID/root
/proc/PID/exe
____________
1 jika opsi
-f
( f ) tidak berfungsi, coba-l
( l azy).2 yaitu, proses yang telah keluar / mati / diakhiri, tetapi orang tuanya belum melakukan a
wait
.sumber
kill(2)
manual menunjukkan secara langsung perilaku yang Anda tunjukkan, tetapi halamanperlfunc
manualnya menunjukkan. Saya akan mengirim email ke Michael Kerrisk untuk mengetahui apa yang dia katakan tentang halaman sistem.kill(2)
perijinan tentang "mengirim" sinyal 0.kill(2)
manual (saya belum melihatnya online): "Jika sig adalah 0, maka tidak ada sinyal yang dikirim, tetapi pemeriksaan keberadaan dan izin masih dilakukan; ini dapat digunakan untuk memeriksa keberadaan suatu ID proses atau ID grup proses yang diizinkan oleh penelepon untuk memberi sinyal. "