Bagaimana cara membunuh skrip yang berjalan di terminal, tanpa menutup terminal (Ctrl + C tidak berfungsi)?

36

Saya telah menulis skrip bash yang memanggil beberapa program lain dan menjalankan banyak perintah. Saya menjalankan skrip ini dari terminal. Sekarang saya ingin membunuh skrip.

Menekan Ctrl + Ckadang tidak memotongnya, saya pikir karena terkadang skrip mengeksekusi program lain, dan untuk beberapa alasan sinyal mematikan tidak berfungsi.

Namun, jika saya menutup jendela terminal, itu akan mematikan skrip.

Apakah ada sesuatu yang dapat saya lakukan (kombinasi keyboard), yang analog dengan menutup jendela terminal, tanpa benar-benar menutup jendela terminal (Saya tidak ingin kehilangan riwayat perintah, direktori saat ini, riwayat keluaran, dll)?

becko
sumber
8
Dalam kasus-kasus seperti itu saya cobaCtrl + z
kenn
Dan setelah Ctrl + zlari:kill -9 $(pgrep -f your_script.sh)
Noam Manos

Jawaban:

38

Anda memiliki beberapa opsi. Salah satunya adalah menghentikan skrip ( CtrlZ), dapatkan PID skrip dan kirim SIGKILLke grup proses.

Ketika sebuah perintah dieksekusi dalam sebuah shell, proses itu dimulai dan semua anak-anaknya adalah bagian dari grup proses yang sama (dalam hal ini, grup proses latar depan). Untuk mengirim sinyal ke semua proses dalam grup ini, Anda mengirimkannya ke pemimpin proses. Untuk killperintah, pemimpin proses dilambangkan sebagai berikut:

kill -PID

Di mana PIDID proses skrip.

Contoh:

Pertimbangkan skrip test.shyang meluncurkan beberapa proses. Katakanlah Anda menjalankannya di shell:

$ ./test.sh

Di terminal lain,

$ pgrep test.sh
17802
$ pstree -ps `!!`
pstree -ps `pgrep test.sh`
init(1)───sshd(1211)───sshd(17312)───sshd(17372)───zsh(17788)───test.sh(17802)─┬─dd(17804)
                                                                               ├─sleep(17805)
                                                                               └─yes(17803)

Dalam hal ini, untuk mengirim sinyal ke grup proses yang dibuat oleh test.sh, Anda harus:

kill -INT -17802

-INTdigunakan untuk mengirim SIGINT, dan perintah ini setara dengan menekan CtrlCpada terminal. Untuk mengirim SIGKILL:

kill -KILL -17802

Anda hanya perlu menghentikan skrip jika Anda tidak dapat membuka terminal lain. Jika Anda bisa, gunakan pgrepuntuk menemukan PID.

Salah satu perintah yang diluncurkan skrip mungkin menjebak SIGINT, yang mungkin mengapa CtrlCtidak efektif. Namun, SIGKILLtidak dapat dijebak, dan ini biasanya merupakan pilihan terakhir . Anda mungkin ingin mencoba SIGTERM( -TERM) sebelum melakukan pembunuhan. Baik SIGKILLatau SIGTERMdapat diatur sebagai cara pintas keyboard seperti SIGINTini.

Semua ini bisa diperdebatkan jika skrip Anda tidak mengandung garis shebang. Dari jawaban SO ini :

Biasanya shell induk menebak bahwa script ditulis untuk shell yang sama (shell Bourne-like minimal menjalankan script dengan / bin / sh, bash menjalankannya sebagai subproses bash) ...

Karena itu, ketika skrip dieksekusi, Anda tidak akan menemukan proses yang dinamai skrip (atau proses dengan nama skrip di baris perintah) dan pgrep akan gagal.

Selalu gunakan garis shebang.

muru
sumber
Apakah ada kombinasi keyboard untuk SIGKILLatau SIGTERM?
becko
@becko Tidak, dan Anda tidak dapat mengaturnya: superuser.com/a/417991/334516
muru
pgrep test.shtidak mengembalikan PID untuk saya. Saya mencoba test.sh sederhana: for i in {1..30}; do sleep 1 echo $i done Ketika test.shsedang berjalan, saya mengeksekusi pgrep test.shdi terminal lain, tetapi tidak ada yang dikembalikan. Apa yang salah?
becko
1
@becko bagaimana Anda menjalankan skrip? Coba juga pgrep -f test.sh.
muru
pgrep -f test.shjuga tidak bekerja. Saya menjalankan skrip dengan./test.sh
becko
6

Jika Anda mengetahui proses yang terkait dengan skrip Anda dapat menemukan PID mereka menggunakan

 ps -A

dan kemudian menggunakan nomor PID untuk mematikan proses yang terkait menggunakan

 kill -9 PID_Number
Harris
sumber
1
Itu terlalu rumit. Script ini memunculkan beberapa program lain, dan program ini juga menelurkan proses paralel. Sangat sulit untuk melacak semua proses ini. Pasti ada solusi yang lebih sederhana, sesuatu yang analog dengan apa yang terjadi ketika Anda menutup jendela terminal.
becko
Bisakah Anda mencoba pkill -P $$
Harris
1

Seperti yang dikatakan Harris, Anda dapat menjalankan Kill -9 PID_Numbertetapi Anda juga dapat menginstal paket yang dikenal htopmemiliki peramban proses interaktif yang membuat proses pencarian lebih mudah. htop juga mendukung proses pembunuhan.

Kurang tidur Bulbasaur
sumber