Dalam sebuah komentar atas jawaban dari pertanyaan lain ini , pemberi komentar berkata:
jangan gunakan kill -9 kecuali benar-benar diperlukan! SIGKILL tidak dapat dijebak sehingga program yang dimatikan tidak dapat menjalankan rutinitas shutdown apa pun untuk misalnya menghapus file-file sementara. Pertama coba HUP (1), lalu INT (2), lalu QUIT (3)
Saya setuju pada prinsipnya tentang SIGKILL
, tetapi sisanya adalah berita bagi saya. Mengingat bahwa sinyal default yang dikirim oleh kill
adalah SIGTERM
, saya berharap itu adalah sinyal yang paling umum diharapkan untuk mematikan proses arbitrer dengan baik. Juga, saya telah melihat SIGHUP
digunakan untuk alasan non-terminating, seperti memberitahu daemon "baca ulang file konfigurasi Anda." Dan menurut saya SIGINT
(interupsi yang sama yang biasanya Anda dapatkan dengan Ctrl-C, kan?) Tidak didukung secara luas sebagaimana mestinya, atau berakhir dengan agak tidak wajar.
Mengingat itu SIGKILL
adalah pilihan terakhir - Sinyal mana, dan dalam urutan apa , yang harus Anda kirimkan ke proses sewenang-wenang, untuk menghentikannya seanggun mungkin?
Harap dukung jawaban Anda dengan fakta pendukung (di luar preferensi atau opini pribadi) atau referensi, jika Anda bisa.
Catatan: Saya sangat tertarik dengan praktik terbaik yang mencakup pertimbangan bash / Cygwin.
Edit: Sejauh ini, sepertinya tidak ada yang menyebut INT atau QUIT, dan HUP juga terbatas. Apakah ada alasan untuk memasukkan ini ke dalam proses pembunuhan yang teratur?
sumber
Jawaban:
SIGTERM memberi tahu aplikasi untuk dihentikan. Sinyal lain memberi tahu aplikasi hal-hal lain yang tidak terkait dengan penghentian tetapi terkadang memiliki hasil yang sama. Jangan gunakan itu. Jika Anda ingin aplikasi ditutup, beri tahu. Jangan berikan sinyal yang menyesatkan.
Beberapa orang percaya bahwa cara standar cerdas untuk menghentikan suatu proses adalah dengan mengirimkannya banyak sinyal, seperti HUP, INT, TERM, dan akhirnya KILL. Ini konyol. Sinyal yang tepat untuk penghentian adalah SIGTERM dan jika SIGTERM tidak menghentikan proses secara instan, seperti yang Anda inginkan, itu karena aplikasi telah memilih untuk menangani sinyal. Artinya, ada alasan yang sangat bagus untuk tidak segera dihentikan: Ada pekerjaan pembersihan yang harus dilakukan. Jika Anda menghentikan pekerjaan pembersihan itu dengan sinyal lain, tidak ada yang tahu data apa dari memori yang belum disimpan ke disk, aplikasi klien apa yang dibiarkan hang atau apakah Anda menyela "kalimat tengah" yang secara efektif merusak data.
Untuk informasi lebih lanjut tentang arti sebenarnya dari sinyal-sinyal itu, lihat sigaction (2). Jangan bingung antara "Tindakan Default" dengan "Deskripsi", keduanya bukanlah hal yang sama.
SIGINT digunakan untuk memberi sinyal "interupsi keyboard" interaktif dari proses tersebut. Beberapa program mungkin menangani situasi ini dengan cara khusus untuk tujuan pengguna terminal.
SIGHUP digunakan untuk memberi sinyal bahwa terminal telah menghilang dan tidak lagi melihat prosesnya. Itu semuanya. Beberapa proses memilih untuk dimatikan sebagai respons, umumnya karena operasinya tidak masuk akal tanpa terminal, beberapa memilih untuk melakukan hal lain seperti memeriksa ulang file konfigurasi.
SIGKILL digunakan untuk secara paksa menghapus proses dari kernel. Ini khusus dalam arti bahwa ini sebenarnya bukan sinyal untuk proses tetapi ditafsirkan oleh kernel secara langsung.
Jangan kirim SIGKILL. SIGKILL seharusnya tidak pernah dikirim melalui skrip. Jika aplikasi menangani SIGTERM, diperlukan beberapa saat untuk membersihkan, dapat memerlukan waktu satu menit, dapat memakan waktu satu jam . Bergantung pada apa yang harus dilakukan aplikasi sebelum siap untuk diakhiri. Logika apa pun yang " mengasumsikan " urutan pembersihan aplikasi telah memakan waktu cukup lama dan perlu dipintas atau SIGKILL setelah X detik benar- benar salah .
Satu-satunya alasan mengapa aplikasi memerlukan SIGKILL untuk dihentikan, adalah jika ada sesuatu yang mengganggu selama urutan pembersihannya. Dalam hal ini Anda dapat membuka terminal dan SIGKILL secara manual. Selain itu, satu-satunya alasan lain mengapa Anda SIGKILL sesuatu adalah karena Anda INGIN mencegahnya membersihkan dirinya sendiri.
Meskipun separuh dunia secara membabi buta mengirim SIGKILL setelah 5 detik, itu masih hal yang sangat salah untuk dilakukan.
sumber
Jawaban Singkat : Kirim
SIGTERM
, 30 detik kemudianSIGKILL
,. Yaitu, kirimSIGTERM
, tunggu sebentar (mungkin berbeda dari satu program ke program lainnya, Anda mungkin lebih mengenal sistem Anda, tetapi 5 hingga 30 detik sudah cukup. Saat mematikan mesin, Anda mungkin melihatnya secara otomatis menunggu hingga 1'30-an. Kenapa terburu-buru?), Lalu kirimSIGKILL
.Wajar Jawaban :
SIGTERM
,SIGINT
,SIGKILL
ini lebih dari cukup. Prosesnya kemungkinan besar akan berakhir sebelumnyaSIGKILL
.Panjang Jawaban :
SIGTERM
,SIGINT
,SIGQUIT
,SIGABRT
,SIGKILL
Ini tidak perlu, tetapi setidaknya Anda tidak menyesatkan proses terkait pesan Anda. Semua sinyal-sinyal yang berarti Anda ingin proses untuk menghentikan apa yang dilakukannya dan keluar.
Apa pun jawaban yang Anda pilih dari penjelasan ini, ingatlah itu!
Jika Anda mengirim sinyal yang berarti sesuatu yang lain, prosesnya mungkin menanganinya dengan cara yang sangat berbeda (di satu sisi). Di sisi lain, jika proses tidak menangani sinyal, tidak peduli apa yang Anda kirim, proses akan tetap berhenti (ketika tindakan default adalah untuk menghentikan, tentu saja).
Jadi, Anda harus berpikir sebagai diri Anda sendiri sebagai seorang programmer. Apakah Anda akan membuat kode penangan fungsi untuk, katakanlah,
SIGHUP
untuk keluar dari program yang terhubung dengan sesuatu, atau apakah Anda akan mengulanginya untuk mencoba menghubungkan lagi? Itulah pertanyaan utama di sini! Itulah mengapa penting untuk hanya mengirimkan sinyal yang sesuai dengan keinginan Anda.Jawaban Panjang yang Hampir Bodoh :
Tabel di bawah ini berisi sinyal yang relevan, dan tindakan default jika program tidak menanganinya.
Saya memesannya dalam urutan yang saya sarankan untuk digunakan (BTW, saya sarankan Anda untuk menggunakan jawaban yang masuk akal , bukan yang ini di sini), jika Anda benar-benar perlu mencoba semuanya (akan menyenangkan untuk mengatakan tabel dipesan dalam hal kehancuran yang mungkin mereka sebabkan, tetapi itu tidak sepenuhnya benar).
Sinyal dengan tanda bintang (*) TIDAK disarankan. Hal penting tentang ini adalah Anda mungkin tidak pernah tahu apa yang diprogram untuk dilakukan. Khususnya
SIGUSR
! Ini mungkin memulai kiamat (itu adalah sinyal gratis bagi programmer untuk melakukan apa pun yang dia inginkan!). Tapi, jika tidak ditangani ATAU dalam kasus yang tidak mungkin ditangani untuk dihentikan, program akan berhenti.Dalam tabel, sinyal dengan opsi default untuk menghentikan dan menghasilkan core dump ditinggalkan pada akhirnya, tepat sebelumnya
SIGKILL
.Maka saya akan menyarankan untuk ini jawaban yang panjang hampir bodoh :
SIGTERM
,SIGINT
,SIGHUP
,SIGPIPE
,SIGQUIT
,SIGABRT
,SIGKILL
Dan akhirnya, file
Jawaban Panjang yang Pasti Bodoh :
Jangan coba ini di rumah.
SIGTERM
,SIGINT
,SIGHUP
,SIGPIPE
,SIGALRM
,SIGUSR2
,SIGUSR1
,SIGQUIT
,SIGABRT
,SIGSEGV
,SIGILL
,SIGFPE
Dan jika tidak ada yang berhasil,SIGKILL
.SIGUSR2
harus dicoba sebelumnyaSIGUSR1
karena kita lebih baik jika program tidak menangani sinyalnya. Dan lebih mungkin untuk menanganiSIGUSR1
jika menangani hanya salah satu dari mereka.BTW, the KILL : tidak salah mengirim
SIGKILL
ke suatu proses, seperti jawaban lain yang dinyatakan. Nah, pikirkan apa yang terjadi ketika Anda mengirimshutdown
perintah? Ini akan mencobaSIGTERM
danSIGKILL
hanya. Menurut Anda mengapa demikian? Dan mengapa Anda membutuhkan sinyal lain, jikashutdown
perintah itu hanya menggunakan dua sinyal ini?Sekarang, kembali ke jawaban panjang , ini adalah satu kalimat yang bagus:
for SIG in 15 2 3 6 9 ; do echo $SIG ; echo kill -$SIG $PID || break ; sleep 30 ; done
Ia tidur selama 30 detik di antara sinyal. Mengapa lagi Anda membutuhkan oneliner ? ;)
Juga, disarankan: coba hanya dengan sinyal
15 2 9
dari jawaban yang masuk akal .keamanan : lepaskan detik
echo
saat Anda siap untuk pergi. Saya menyebutnya milik sayadry-run
untuk onliner . Selalu gunakan untuk menguji.Script membunuh
Sebenarnya saya sangat tertarik dengan pertanyaan ini sehingga saya memutuskan untuk membuat skrip kecil untuk melakukan hal itu. Silakan, silakan unduh (klon) di sini:
Tautan GitHub ke repositori Killgracefully
sumber
Biasanya Anda akan mengirim
SIGTERM
, default kill. Ini default karena suatu alasan. Hanya jika sebuah program tidak ditutup dalam jangka waktu yang wajar, Anda harus melakukannyaSIGKILL
. Tetapi perhatikan bahwa denganSIGKILL
program tidak ada kemungkinan untuk membersihkan hal-hal dan data bisa rusak.Adapun
SIGHUP
,HUP
singkatan dari "menutup telepon" dan secara historis berarti modem terputus. Ini pada dasarnya sama denganSIGTERM
. Alasan mengapa daemon terkadang digunakanSIGHUP
untuk memulai ulang atau memuat ulang konfigurasi adalah karena daemon terlepas dari terminal pengendali mana pun karena daemon tidak memerlukannya dan oleh karena itu tidak akan pernah menerimaSIGHUP
, sehingga sinyal dianggap "dibebaskan" untuk penggunaan umum. Tidak semua daemon menggunakan ini untuk memuat ulang! Tindakan default untuk SIGHUP adalah menghentikan dan banyak daemon berperilaku seperti itu! Jadi Anda tidak bisa begitu saja mengirimkanSIGHUP
daemon dan mengharapkan mereka untuk bertahan hidup.Sunting:
SIGINT
mungkin tidak tepat untuk menghentikan suatu proses, karena biasanya terkait dengan^C
atau apa pun pengaturan terminal untuk mengganggu program. Banyak program menangkap ini untuk tujuan mereka sendiri, jadi cukup umum untuk tidak berhasil.SIGQUIT
biasanya memiliki default untuk membuat core dump, dan kecuali Anda ingin file inti diletakkan di sekitarnya, itu juga bukan kandidat yang baik.Ringkasan: jika Anda mengirim
SIGTERM
dan program tidak mati dalam jangka waktu Anda, maka kirimkanSIGKILL
.sumber
SIGTERM
sebenarnya berarti mengirim pesan ke aplikasi: " maukah kamu menjadi begitu baik dan bunuh diri ". Itu bisa terjebak dan ditangani oleh aplikasi untuk menjalankan kode pembersihan dan shutdown.SIGKILL
tidak bisa terjebak oleh aplikasi. Aplikasi dimatikan oleh OS tanpa ada kesempatan untuk dibersihkan.Biasanya mengirim
SIGTERM
dulu, tidur sebentar, lalu mengirimSIGKILL
.sumber
sumber
Dengan semua diskusi yang berlangsung di sini, tidak ada kode yang ditawarkan. Ini pendapat saya:
#!/bin/bash $pid = 1234 echo "Killing process $pid..." kill $pid waitAttempts=30 for i in $(seq 1 $waitAttempts) do echo "Checking if process is alive (attempt #$i / $waitAttempts)..." sleep 1 if ps -p $pid > /dev/null then echo "Process $pid is still running" else echo "Process $pid has shut down successfully" break fi done if ps -p $pid > /dev/null then echo "Could not shut down process $pid gracefully - killing it forcibly..." kill -SIGKILL $pid fi
sumber
HUP terdengar seperti sampah bagi saya. Saya akan mengirimkannya agar daemon membaca ulang konfigurasinya.
SIGTERM dapat dicegat; daemon Anda mungkin memiliki kode pembersihan untuk dijalankan ketika menerima sinyal itu. Anda tidak dapat melakukan itu untuk SIGKILL. Jadi dengan SIGKILL Anda tidak memberikan opsi apa pun kepada pembuat daemon.
Lebih lanjut tentang itu di Wikipedia
sumber