Jawaban:
Untuk memeriksa keberadaan suatu proses, gunakan
kill -0 $pid
Tapi seperti yang dikatakan @wwind, jika kamu akan membunuhnya, cukup
kill $pid
atau Anda akan memiliki kondisi balapan.
Jika Anda ingin mengabaikan output teks kill
dan melakukan sesuatu berdasarkan kode keluar, Anda bisa
if ! kill $pid > /dev/null 2>&1; then
echo "Could not send SIGTERM to process $pid" >&2
fi
kill
agak keliru karena tidak selalu membunuh prosesnya. Itu hanya mengirimkan proses sinyal. kill $PID
setara dengan kill -15 $PID
, yang mengirimkan sinyal 15, SIGTERM ke proses, yang merupakan instruksi untuk mengakhiri. Tidak ada sinyal 0, itu adalah nilai khusus yang mengatakan kill
untuk hanya memeriksa apakah sinyal dapat dikirim ke proses, yang untuk sebagian besar tujuan kurang lebih setara dengan memeriksa jika ada. Lihat linux.die.net/man/2/kill dan linux.die.net/man/7/signal
kill -0
, saya, pada kenyataannya, harus melakukan ini: kill -0 25667 ; echo $?
- dan kemudian jika saya mendapatkan 0
kembali, maka proses dengan PID itu dapat dibunuh; dan jika proses PID (katakanlah) tidak ada, $?
akan 1
, menunjukkan kegagalan. Apakah itu benar?
Cara terbaik adalah:
if ps -p $PID > /dev/null
then
echo "$PID is running"
# Do something knowing the pid exists, i.e. the process with $PID is running
fi
Masalah dengan:
kill -0 $PID
adalah kode keluar akan menjadi nol bahkan jika pid sedang berjalan dan Anda tidak memiliki izin untuk membunuhnya. Sebagai contoh:
kill -0 1
dan
kill -0 $non-running-pid
memiliki kode keluar yang tidak dapat dibedakan (tidak nol) untuk pengguna normal, tetapi proses init (PID 1) sudah pasti berjalan.
Jawaban yang membahas kondisi membunuh dan ras benar jika tubuh tes adalah "membunuh". Saya datang mencari jenderal " bagaimana Anda menguji keberadaan PID di bash ".
Metode / proc itu menarik, tetapi dalam beberapa hal mematahkan semangat abstraksi perintah "ps", yaitu Anda tidak perlu pergi mencari di / proc karena bagaimana jika Linus memutuskan untuk memanggil file "exe" sesuatu yang lain?
-p
itu tidak perlu, setidaknya dalam kasus itu. ps $PID
memiliki hasil yang sama persis.
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
atau
if [ -n "$(ps -p $PID -o pid=)" ]
Dalam bentuk yang terakhir, -o pid=
adalah format output untuk menampilkan hanya kolom ID proses tanpa header. Kutipan diperlukan untuk operator string yang tidak kosong -n
untuk memberikan hasil yang valid.
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ps
opsi dan fitur cenderung bervariasi antar platform, sehingga masih belum sepenuhnya portabel.
$PID
kosong maka [ -e /proc/$PID ]
akan tetap benar, karena /proc/
direktori masih ada.
Anda memiliki dua cara:
Mari kita mulai dengan mencari aplikasi spesifik di laptop saya:
[root@pinky:~]# ps fax | grep mozilla
3358 ? S 0:00 \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2 S+ 0:00 \_ grep mozilla
Semua contoh sekarang akan mencari PID 3358.
Cara pertama : Jalankan "ps aux" dan grep untuk PID di kolom kedua. Dalam contoh ini saya mencari firefox, dan kemudian untuk itu PID:
[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358
Jadi kode Anda adalah:
if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
kill $PID
fi
Cara kedua : Cukup cari sesuatu di /proc/$PID
direktori. Saya menggunakan "exe" dalam contoh ini, tetapi Anda dapat menggunakan hal lain.
[root@pinky:~]# ls -l /proc/3358/exe
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash
Jadi kode Anda adalah:
if [ -f /proc/$PID/exe ]; then
kill $PID
fi
BTW: ada apa dengan itu kill -9 $PID || true
?
EDIT:
Setelah memikirkannya selama beberapa bulan .. (sekitar 24 ...) ide orisinal yang saya berikan di sini adalah hack yang bagus, tetapi sangat tidak bisa diport. Sementara itu mengajarkan beberapa detail implementasi Linux, itu akan gagal bekerja pada Mac, Solaris atau * BSD Bahkan mungkin gagal di kernel Linux masa depan. Silakan - gunakan "ps" seperti yang dijelaskan dalam tanggapan lain.
/proc/$PID/exe
bukan file biasa. Jadi, [ -f /proc/$PID/exe ]
akan selalu mengembalikan false
hasilnya. Coba [ -h /proc/$PID/exe ]
.
Sepertinya kamu mau
wait $PID
yang akan kembali saat $pid
selesai.
Kalau tidak, Anda bisa menggunakan
ps -p $PID
untuk memeriksa apakah prosesnya masih hidup (ini lebih efektif daripada kill -0 $pid
karena itu akan bekerja bahkan jika Anda tidak memiliki pid).
pid 123 is not a child of this shell
Saya pikir itu adalah solusi buruk, yang membuka untuk kondisi balapan. Bagaimana jika proses mati antara pengujian Anda dan panggilan Anda untuk membunuh? Maka membunuh akan gagal. Jadi mengapa tidak coba saja kill dalam semua kasus, dan periksa nilai kembalinya untuk mengetahui bagaimana hasilnya?
kill -9
. Itu hanya langsung membunuh proses sehingga tidak ada kesempatan untuk membersihkan setelah itu sendiri. Alih-alih menggunakan kill
yang setara dengan kill -15
. Jika itu tidak berhasil, Anda harus mencari tahu alasannya, dan hanya sebagai penggunaan terakhir kill -9
.
di sini saya menyimpan PID dalam file bernama .pid (yang seperti / run / ...) dan hanya menjalankan skrip jika belum dieksekusi.
#!/bin/bash
if [ -f .pid ]; then
read pid < .pid
echo $pid
ps -p $pid > /dev/null
r=$?
if [ $r -eq 0 ]; then
echo "$pid is currently running, not executing $0 twice, exiting now..."
exit 1
fi
fi
echo $$ > .pid
# do things here
rm .pid
Catatan: ada kondisi lomba karena tidak memeriksa bagaimana pid itu disebut. jika sistem di-boot ulang dan .pid ada tetapi digunakan oleh aplikasi yang berbeda ini dapat menyebabkan 'konsekuensi yang tidak terduga'.
Sebagai contoh di GNU / Linux Anda dapat menggunakan:
Pid=$(pidof `process_name`)
if [ $Pid > 0 ]; then
do something
else
do something
fi
Atau semacamnya
Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN
dan itu menunjukkan Anda nama aplikasi, hanya nama tanpa ID.
pidof
tidak mengembalikan angka negatif, karena PID negatif tidak masuk akal, dan Anda tidak dapat membunuh init
, sehingga persyaratan Anda tidak masuk akal (dan selain itu, Anda harus melarikan diri dari >
untuk mencegahnya melakukan pengalihan). Anda ingin memeriksa hasil yang kosong, tetapi tentu saja, seperti alat yang layak, pidof
menetapkan kode keluar untuk memberi tahu Anda apakah itu berhasil, jadi solusi yang tepat adalah if Pid=$(pidof 'process_name'); then ...
atau (jika Anda tidak memerlukan nilainya Pid
nanti) cukupif pidof 'process_name'; then...
pidof
contohnya penuh dengan kesalahpahaman tentang cara test
kerja bash . gnu.org/software/bash/manual/html_node/…
kode di bawah memeriksa apakah proses saya sedang berjalan, jika tidak melakukan apa-apa.
mari kita periksa pesan baru dari Amazon SQS setiap jam saja dan hanya jika prosesnya tidak berjalan.
#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
/usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
echo "do nothing, just smile =)"
fi
exit $?