Apa perbedaan antara Ctrl-Z dan kill -STOP?

14

Ketika saya menjalankan perintah ( makepada proyek besar) dari shell, saya bisa mengetik Ctrl-Z untuk menghentikan proses dan kembali ke shell. Selanjutnya, saya bisa lari fguntuk melanjutkan proses.

Saya mencoba menulis skrip shell untuk mengotomatisasi ini (khususnya, untuk memeriksa suhu CPU saya setiap beberapa detik dan menghentikan proses jika terlalu panas, karena komputer saya cenderung terlalu panas). Upaya pertama saya berhasil seperti ini (disederhanakan):

make &
subpid="$!"

sleep 2
# If the CPU temperature is too high...
kill -STOP "$subpid"

sleep 2
# If the CPU temperature has dropped to safe levels...
kill -CONT "$subpid"

wait "$subpid"

Sayangnya, ini tidak berhasil; mengirim SIGSTOP ke proses tidak menghentikannya (seperti yang dibuktikan dengan terus mengirim output ke terminal). Saya berlari make &di baris perintah, mengirim SIGSTOP, dan memeriksa status proses dengan ps; itu terdaftar sebagai berhenti (dan mulai lagi ketika saya mengirim SIGCONT), tetapi masih memuntahkan output dan menaikkan suhu inti saya! Menghentikannya dengan Ctrl-Z tidak pernah mengalami masalah ini, tapi saya tidak tahu bagaimana melakukannya dalam sebuah skrip.

Apa yang membuat Ctrl-Z berbeda kill -STOP, dan bagaimana saya bisa mendapatkan perilaku sebelumnya dalam skrip shell?

Taymon
sumber
Dan ya, makedijalankan secara rekursif. Bahkan, saya pikir itu masuk beberapa level.
Taymon

Jawaban:

12

Apa yang membuat Ctrl-Z berbeda kill -STOP, dan bagaimana saya bisa mendapatkan perilaku sebelumnya dalam skrip shell?

CTRL-Zbiasanya mengirimkan SIGTSTP (yang dapat diblokir), dan - terlepas dari hal-hal lain - kerang sering mengatur ulang tty ke keadaan yang sebelumnya disimpan pada kesempatan ini. Namun yang lebih penting, grup proses terminal pengendali diatur ke PID shell (dan sekali lagi ke PID pekerjaan yang dilanjutkan dengan fg).

Kembali ke masalah awal Anda: menggunakan penskalaan frekuensi yang tergantung suhu seperti misalnya Cpufreqd sebenarnya bisa menjadi palu yang lebih baik untuk kuku Anda.

peterph
sumber
4

Anda tidak ingin menghentikan makeprosesnya; Anda ingin menghentikan makeproses dan semua proses anaknya. Saya yakin make sedang dijalankan secara rekursif.

Anda dapat mencoba set -m, kemudian gunakan %1bukan "$subpid".

Yang set -mmemungkinkan "kontrol pekerjaan", yang dinonaktifkan secara default di dalam skrip. Saya pikir itu harus bekerja untuk kasus penggunaan Anda, meskipun orang tampaknya berpikir itu adalah ide yang buruk secara umum .

sourcejedi
sumber
4

Anda dapat mengirim sinyal ke semua proses dalam grup proses jika Anda menentukan nilai PID negatif - PGID pemimpin sesi.

kill -STOP -"$subpid"

Catatan: Untuk menjalankan program dalam penggunaan sesi baru setsid make. Tetapi dalam kasus Anda, saya pikir itu tidak diperlukan. Namun, jika make dijalankan secara rekursif, setiap instance make dapat menjadi pemimpinnya sendiri (saya tidak yakin tentang itu).

Opsi lain bisa menggunakan killall:

killall -STOP make

Perbedaan antara Ctrl + Z dan kill -STOP:

  • Ctrl-Z sebenarnya mengirim TSTP, yang dapat diblokir.
  • STOP tidak dapat diblokir.
Jurij
sumber
Pendekatan PGID tidak bekerja, dan diproduksi baris berikut output: /usr/local/bin/myscript: line 38: kill: (-10202) - No such process. Proses latar belakang terus berjalan. Saya tidak berpikir killallpendekatan itu akan berhasil karena beberapa subproses tampaknya shlebih daripada make.
Taymon
Tampaknya proses pengiriman sinyal sudah selesai. Subproses bernama sh dihasilkan oleh make. Dalam kasus Anda membuat dan banyak subproses yang terbaik mungkin akan mendapatkan PID dari semua anak dan BERHENTI semuanya.
Jurij
Itu akhirnya bekerja ketika saya melakukannya secara manual dari shell, tetapi tidak dalam skrip shell. Saya pikir ini karena ketika saya melakukannya secara manual, PID root (yang lain mewarisi PGID dari mereka) adalah makeperintah pertama , tetapi ketika saya melakukannya dari skrip, root PID berasal dari skrip shell itu sendiri .
Taymon
1

Ctrl+ Cdigunakan untuk membunuh proses dengan sinyal SIGINT, dengan kata lain itu adalah pembunuhan yang sopan .

Ctrl+ Z digunakan untuk menunda proses dengan mengirimkannya sinyal SIGSTP , yang seperti sinyal tidur, yang dapat dibatalkan dan proses dapat dilanjutkan kembali.

Namun ketika suatu proses ditangguhkan, kita dapat melanjutkannya kembali dengan fg (melanjutkan di latar depan) dan bg (melanjutkan di latar belakang) , tetapi saya tidak dapat melanjutkan proses yang terbunuh, itu adalah perbedaan antara menggunakan Ctrl+ C& Ctrl+ Z.

Bagaimana cara melihat proses yang ditangguhkan?

Ketika Anda memiliki beberapa perintah yang ditangguhkan, agar terdaftar, Anda menggunakan jobsperintah, dan hasilnya adalah:

[1]-  Stopped                 cat
[2]+  Stopped                 vi

Bagaimana cara membunuh proses yang ditangguhkan di latar belakang?

Dengan menggunakan killperintah:

kill %ndi mana n adalah jumlah pekerjaan (yang dalam kurung persegi dari output pekerjaan), jadi saya ingin membunuh kucing: kill %1.

antzshrek
sumber