Mengapa Ctrl-C tidak mematikan Terminal itu sendiri?

39

Terminal berjalan ketika kita membukanya.

luvpreet@DHARI-Inspiron-3542:/$

Saya baru saja membukanya. Jadi, ketika saya menekan Ctrl+ C, mengapa itu tidak mematikan dirinya sendiri dan menutup terminal ??

luv.preet
sumber
21
terminal tidak berjalan di terminal ;-)
Pilot6
3
mengenai mengapa control-d berfungsi: unix.stackexchange.com/a/110248/14305
Janus Troelsen

Jawaban:

48

Ctrl+ Cadalah sinyal interupsi. Saat Anda mengetik ini di terminal, bash mengirim SIGINT ke pekerjaan di latar depan. Jika tidak ada pekerjaan (yang merupakan kasus ketika Anda baru saja membuka terminal), tidak ada yang terjadi. Program emulator terminal bukanlah pekerjaan yang berjalan di shell, jadi, itu tidak mendapatkan sinyal dan tidak menutup.

Jika Anda ingin menutup terminal dengan kunci kontrol, gunakan Ctrl+ D(EOF) yang menyebabkan bash keluar (dan juga menutup terminal).

Lihat juga: Bash Beginner's Guide pada sinyal dan secara lebih mendalam Bagaimana penanganan sinyal bekerja
perhatikan: jawaban ini telah diedit sejak komentar diposting

Zanna
sumber
4
Istilah yang tepat adalah bahwa shell akan "menjebak" sinyal. Cerita berbeda adalah ketika Anda meluncurkan jendela terminal dari dalam jendela lain. Mengirim ctrl + c ke jendela induk akan mematikan proses anak.
Sergiy Kolodyazhnyy
1
Selain itu, jendela GUI juga dapat diperintahkan untuk menjebak sinyal khusus yang datang dari server X11. Begitulah cara Anda memiliki popup yang memberi tahu Anda tentang pekerjaan yang belum disimpan, atau membuka tab seperti di browser
Sergiy Kolodyazhnyy
8
@chrylis program terminal hanya mengirim karakter ctrl-c, sebenarnya lapisan tty kernel yang mengubahnya menjadi sinyal.
Random832
3
@chrylis: Dan terminal, atau program yang berjalan di dalamnya - misalnya editor teks - mungkin menerjemahkan Ctl-C ke beberapa tindakan lain.
jamesqf
3
Saya tidak berpikir bashakan menghentikan program apa pun ketika ctrl-c ditekan. Ini hanya akan memberi tahu kernel grup proses mana yang aktif dan kernel akan menghasilkan sinyal ke grup proses tersebut ketika menerima ctrl-c dari program terminal.
kasperd
32

The ^Ckeystroke, seperti penekanan tombol lain *, bukan sihir - itu mengirimkan keycode ke mana program yang memiliki fokus. (Dalam X, kode kunci adalah 54 untuk Cdengan pengubah 0x4 untuk Ctrl.) Program yang menerima aliran kunci bertanggung jawab untuk melakukan sesuatu yang sesuai dengan mereka - ingat bahwa dalam banyak aplikasi GUI, keystroke menyalin ke clipboard.

Ketika emulator terminal GUI (misalnya, Konsole) atau terminal virtual menerima penekanan tombol yang ditafsirkan ^C, ia dapat melakukan salah satu dari tiga hal. Jika terminal di modus baku , maka program berjalan telah meminta terminal tidak melakukan apa pun penanganan tombol khusus itu sendiri dan untuk lulus mereka langsung ke program. Beberapa program yang mendukung fitur-fitur canggih seperti pengeditan garis menerima input keyboard di beberapa konfigurasi di antara penekanan tombol mentah lengkap dan baris teks yang diproses; bash, misalnya, menerima penekanan tombol satu per satu. ^Cditafsirkan oleh terminal, tetapi kunci backspace dikirim ke shell apa adanya.

Namun, sebagian besar program menggunakan mode matang (karena tidak mentah), di mana terminal menginterpretasikan beberapa penekanan tombol dasar sebelum benar-benar mengirimnya ke program (inilah sebabnya Anda dapat menggunakan backspace dalam cat). Dalam mode ini, terminal itu sendiri menerjemahkan ^Ckeystroke menjadi SIGINTsinyal dan mengirimkannya ke proses anak. Karena terminal menghasilkan sinyal, itu tidak akan menjadi bingung dan berakhir.

  • SysRq sungguh ajaib.
chrylis -on strike-
sumber
Jelas tidak sangat relevan di sini, tetapi untuk komputasi umum ada lebih banyak penekanan tombol ajaib di luar sana. Yang paling terkenal, Ctrl+ Alt+ Deletedi dunia Windows, di mana kombinasi kuncinya cukup dekat dengan sulap (dapat digunakan untuk membuat Windows bekerja, itu ajaib di dalam dan dari dirinya sendiri!), Karena kode itu dimasukkan ke dalam sistem untuk mengganggu dan menimpa hampir semua segalanya — sangat mirip dengan SysRqitu.
KRyan
7
Bash tidak menggunakan mode mentah - ia menggunakan mode karakter-at-a-waktu yaitu cbreak/ -icanon, tetapi tidak meninggalkan isigmode yang ditetapkan, dan tidak menerima sinyal nyata ketika Anda menekan tombol yang dipetakan ke mereka. Ini menangani SIGINTdengan berperilaku seperti yang Anda jelaskan (tidak hanya membatalkan pengeditan baris, itu juga membatalkan semua perintah internal yang mungkin berjalan dalam satu lingkaran), dan sepenuhnya mengabaikan SIGTSTPdan SIGQUIT. Program lain, seperti vi, mungkin tidak.
Random832
1
@KRyan Ctrl+ Alt+ Deletedulunya lebih ajaib daripada hari ini - blogs.msdn.microsoft.com/oldnewthing/20140912-00/?p=44083 . Meskipun saya adalah orang yang suka Linux, saya sering terpesona melihat sejauh mana Windows membuat hal-hal yang ramah pengguna dan logis dengan sumber daya yang terbatas di masa-masa awal.
Muzer
Pada beberapa OS, bahkan jika program lain memfokuskan sistem (pengelola jendela, saya kira?) Benar-benar mendapatkan penekanan tombol sebelum emulator terminal melakukannya. Jika Anda dapat mengonfigurasi pintasan keyboard untuk mengambil jendela, buka aplikasi, picu skrip kemudian sebelum tombol yang ditekan dikirim ke emulator terminal, mereka diperiksa untuk pintasan apa pun yang telah Anda konfigurasikan. Dan contoh lain jika Anda tidak memiliki aplikasi yang terbuka ^ctidak akan mematikan window manager :). Tidak dapat mengomentari karakter mentah / matang pada suatu waktu, tetapi jawabannya tepat tentang bagaimana keystroke itu dihasilkanSIGINT
Ajay
2
" Mode matang (karena itu tidak mentah)": Saya ... terdiam. Setelah bertahun-tahun, saya tidak pernah membuat koneksi.
isanae
8

^Cbiasanya dipetakan (lihat stty -a) ke SIGINTsinyal (lihat man 7 signal).

Yang tidak tertangkap SIGINTmengganggu proses yang berjalan, TAPI ...

SIGINT adalah salah satu sinyal bahwa suatu proses dapat menentukan perilaku untuk ("Menangkap sinyal").

Apa yang Anda sebut "terminal" menangkap SIGINT, dan kembali bekerja.

waltinator
sumber
7

Ketika saya masih pemula saya kehilangan bagian bahwa ketika saya menggunakan baris perintah saya sebenarnya menggunakan dua program yang terpisah, terminal dan shell (misalnya bash)

Shell adalah apa yang mungkin sudah Anda ketahui, sebuah program yang mengambil perintah input atau skrip, mengeksekusi mereka dan mencetak hasilnya.

Terminal di sisi lain seperti seorang pria di tengah-tengah antara pengguna dan program (program yang biasanya berupa shell seperti bash atau ikan). Apa yang dilakukan terminal adalah membaca input misalnya dari keyboard, mungkin memproses input itu dengan cara tertentu, dan mengarahkannya ke program lain (bash).

Juga ini bekerja dengan cara lain juga, ketika program lain mengeluarkan sesuatu, bahwa sesuatu dialihkan ke terminal, maka tugas terminal untuk menampilkan sesuatu ke layar. Di antara mendapatkan input dan mencetaknya ke layar terminal dapat menginterpretasikan input yang didapatnya dengan berbagai cara.

Sebagai contoh jika suatu program mengeluarkan urutan berikut:

\e[0;31m some extra foobar text

Terminal akan menampilkan ke layar "beberapa teks foobar tambahan" dengan huruf berwarna merah. Ini karena terminal memilih untuk memperlakukan kode aneh itu dengan cara khusus yang mengisyaratkan kode itu untuk mencetak keluaran berikut dengan warna merah.

Demikian pula ketika pengguna menekan Ctrl - C, satu-satunya hal khusus tentang ini adalah bahwa terminal memilih untuk memperlakukannya dengan cara khusus, tidak ada yang istimewa tentang urutan kunci ini. Secara khusus ini mengisyaratkan untuk mengirim sinyal interupsi (SIGINT) ke proses yang berjalan di dalam terminal, yaitu shell. Jika pada saat itu ada program yang telah dihasilkan oleh shell dan saat ini berjalan di latar depan juga menerima sinyal. Sekarang shell memiliki handler khusus untuk sinyal ini dan tidak ada yang terjadi. Tetapi sebagian besar program memiliki penangan default yang dalam kasus SIGINT hanya keluar.

pengguna183833
sumber
5

Setiap sinyal memiliki aksi default yang terkait dengannya. Tindakan default untuk sinyal adalah tindakan yang dilakukan skrip atau program saat menerima sinyal.

Ctrl+ Cmengirimkan sinyal "interrupt" ( SIGINT ), yang secara default menghentikan proses untuk pekerjaan yang berjalan di latar depan.

Ctrl+ Dmemberi tahu terminal bahwa ia harus mendaftarkan EOF pada input standar, yang mem-bash interpretasikan sebagai keinginan untuk keluar .

Suatu proses dapat memilih untuk mengabaikan sinyal INT, dan Bash melakukannya ketika itu berjalan dalam mode interaktif.

Dari manual :

Ketika bash bersifat interaktif, dengan tidak adanya jebakan, itu mengabaikan SIGTERM (sehingga membunuh 0 tidak membunuh shell interaktif), dan SIGINT ditangkap dan ditangani (sehingga menunggu builtin interruptible). Dalam semua kasus, bash mengabaikan SIGQUIT. Jika kontrol pekerjaan berlaku, bash mengabaikan SIGTTIN, SIGTTOU, dan SIGTSTP.


Pahami dengan perangkap :

trap adalah fungsi yang dibangun ke dalam shell yang merespon sinyal perangkat keras dan peristiwa lainnya. Ini mendefinisikan dan mengaktifkan penangan yang akan dijalankan ketika shell menerima sinyal atau kondisi khusus lainnya.

trap [-lp] [arg] [sigspec …]

-l cetak daftar nama sinyal dan nomor yang sesuai.
-ptampilkan perintah perangkap yang terkait dengan setiap SIGNAL_SPEC.

arg harus dibaca dan dieksekusi ketika shell menerima sinyal sigspec. Setiap sigspec adalah nama sinyal atau nomor sinyal. Nama sinyal tidak peka huruf besar kecil dan awalan SIG adalah opsional.

Jika sigspec adalah 0 atau EXIT , arg dieksekusi ketika shell keluar. Untuk memahaminya, tutup terminal & buka setelah mengedit .bashrcfile baris berikut .

trap 'notify-send "Ctrl D pressed"' 0

Ctrl D mirip dengan exitperintah untuk keluar dari terminal.

Jika Anda ingin Bash keluar setelah menerima sinyal INT, bahkan dalam mode interaktif, Anda dapat menambahkan yang berikut ke ~/.bashrc:

trap 'exit' INT

atau

trap 'exit' 2
bunga aster
sumber
1
sepertinya sah !!
luv.preet