Apa yang dilakukan CTRL + 4 (dan CTRL + \) di bash?

22

Saya baru tahu secara tidak sengaja CTRL+ 4 menutup program yang membaca stdininput dari command-line.

Ini adalah tampilannya ketika saya mengetik CTRL+ 4atau CTRL+ / ke dalam program membacastdin

$ cat
wefwef
wefwef
^\Quit
$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
^\Quit
$

Saya ^\Quitditampilkan dan kemudian program ditutup. Apa perbedaannya dibandingkan dengan menggunakan ^Catau ^D? Apa yang ^\Quitharus dilakukan

Sunting : Ditemukan bahwa CTRL+ \melakukan hal yang sama.

wefwefa3
sumber

Jawaban:

37

Ctrl + 4 mengirim ^ \

Terminal mengirim karakter (atau lebih tepatnya byte), bukan kunci. Ketika tombol yang mewakili karakter yang dapat dicetak ditekan, terminal mengirimkan karakter itu ke aplikasi. Sebagian besar tombol fungsi dikodekan sebagai urutan melarikan diri: urutan karakter yang dimulai dengan nomor karakter 27. Beberapa gantungan kunci dari formulir Ctrl+ character, dan beberapa tombol fungsi, dikirim sebagai karakter kontrol - dalam rangkaian karakter ASCII , di mana semua komputer modern gunakan sebagai basis (Unicode, ISO Latin- n, dll. semuanya adalah superset ASCII), 33 karakter adalah karakter kontrol: karakter nomor 0 hingga 31 dan 127. Karakter kontrol tidak dapat dicetak, tetapi dimaksudkan untuk memiliki efek dalam aplikasi; misalnya karakter 10, yang merupakan Control-J (umumnya ditulis ^ J), adalah karakter baris baru, jadi ketika terminal menampilkan karakter itu, ia memindahkan kursor ke baris berikutnya, daripada menampilkan mesin terbang. Karakter melarikan diri itu sendiri adalah karakter kontrol, ^ [(nilai 27).

Tidak ada karakter kontrol yang cukup untuk mencakup semua Ctrl+ charactergantungan kunci. Hanya huruf dan karakter yang @[\]^_?memiliki karakter kontrol yang sesuai. Ketika Anda menekan Ctrl+ 4atau Ctrl+ $(yang saya duga adalah Ctrl+ Shift+ 4), terminal harus memilih sesuatu untuk dikirim. Tergantung pada terminal dan konfigurasinya, ada beberapa kemungkinan umum:

  • Terminal mengabaikan Ctrlpengubah dan mengirim karakter 4atau $.
  • Terminal mengirimkan urutan pelarian yang menyandikan kunci dan pengubah yang tepat yang ditekan.
  • Terminal mengirimkan beberapa karakter kontrol lainnya.

Banyak terminal mengirim karakter kontrol untuk beberapa kunci di baris digit:

  • Ctrl+ 2→ ^ @
  • Ctrl+ 3→ ^ [
  • Ctrl+ 4→ ^ \
  • Ctrl+ 5→ ^]
  • Ctrl+ 6→ ^^
  • Ctrl+ 7→ ^ _
  • Ctrl+ 8→ ^?

Saya tidak tahu di mana kebaktian khusus ini muncul.

Ctrl+ |mengirimkan karakter yang sama karena itu Ctrl+ Shift+ \dan terminal mengirimkan ^ \ apakah tombol shift ditekan atau tidak.

^ \ berhenti

Terminal itu sendiri (lebih tepatnya, dukungan terminal generik di kernel) menafsirkan beberapa karakter kontrol khusus. Interpretasi ini dapat dikonfigurasi untuk memetakan karakter yang berbeda atau dimatikan oleh aplikasi yang ingin memproses karakter sendiri. Salah satu interpretasi yang terkenal adalah bahwa ^ M, karakter yang dikirim oleh Returnkunci, mengirimkan baris saat ini ke aplikasi, jika terminal dalam mode matang , di mana aplikasi menerima input baris demi baris.

Beberapa karakter mengirim sinyal ke aplikasi di latar depan. ^ C mengirimkan sinyal interupsi (SIGINT), yang secara konvensional memberi tahu aplikasi untuk menghentikan apa yang dilakukannya dan membaca perintah pengguna selanjutnya. Aplikasi non-interaktif biasanya keluar. ^ \ mengirimkan sinyal keluar (SIGQUIT), yang secara konvensional memberi tahu aplikasi untuk keluar sesegera mungkin tanpa menyimpan apa pun; banyak aplikasi tidak mengesampingkan perilaku default, yaitu mematikan aplikasi dengan segera¹. Jadi, ketika Anda menekan Ctrl+ 4(atau apa pun yang mengirim karakter ^ \) di catatau bc, tidak ada yang menimpa perilaku default, aplikasi terbunuh.

Terminal itu sendiri mencetak ^\bagian dari pesan: itu adalah penggambaran visual dari karakter yang Anda ketikkan, dan terminal dalam mode matang dan dengan gema dihidupkan (karakter ditampilkan oleh terminal segera setelah Anda mengetiknya, sebagai lawan dari mode non-gema di mana karakter hanya dikirim ke aplikasi, yang mungkin atau mungkin tidak memilih untuk menampilkannya). Bagian ini Quitberasal dari bash: ia memperhatikan bahwa proses anaknya mati karena sinyal berhenti, dan itulah cara untuk memberi tahu Anda.

Kerang menangani semua sinyal umum, sehingga jika Anda mengetikkan ^ \ dalam sebuah shell, Anda tidak membunuh sesi Anda, Anda hanya mendapatkan prompt baru, sama seperti ^ C.

Anda dapat bermain dengan pengaturan terminal dengan sttyperintah.

¹ Dan secara tradisional menghasilkan dump inti , tetapi banyak sistem menonaktifkannya secara default saat ini.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
SIGINT membunuh kelompok proses latar depan dan SIGQUIT membunuhnya dengan dump inti. Kedua sinyal dapat ditangani. Saya tidak yakin apa yang Anda maksud dengan membaca perintah selanjutnya . Sistem tidak menonaktifkan dump inti selain dengan menetapkan batas awal coredumpsize ke 0 (bukan yang sulit, Anda biasanya bebas untuk menaikkannya).
Stéphane Chazelas
@ StéphaneChazelas Dalam program yang melakukan interaksi pengguna, semantik SIGINT yang biasa adalah untuk membatalkan perintah pengguna saat ini dan memungkinkan pengguna untuk berinteraksi dengan program, yaitu untuk kembali ke loop perintah utama. Di sisi lain, saya tidak ingat pernah melihat program di mana SIGQUIT tidak berhenti (kecuali bug di penangan sinyal). Memang cara banyak sistem menonaktifkan dump inti secara default adalah dengan menetapkan batas lunak ukuran dump core ke 0, membuat pengguna bebas untuk mengubah pengaturan default ini jika mereka mau.
Gilles 'SANGAT berhenti menjadi jahat'
Itu pengecualian. SIGINT membunuh tugas yang sedang berjalan. Hanya beberapa aplikasi yang akan memperpanjang itu untuk membunuh tugas "foreground" mereka sendiri. Anda harus memikirkan lessatau vim. Perhatikan bahwa dalam cmd | less, CTRL-Cbiasanya membunuh cmd(sedangkan untuk lessitu ditangani untuk membatalkan tindakan saat ini (seperti pencarian)) (lanjutan)
Stéphane Chazelas
Saya menemukan kata-kata dari jawaban Anda membingungkan dalam hal itu. Fakta bahwa SIGQUIT umumnya tidak ditangani adalah bahwa SIGQUIT tidak digunakan dengan cara yang sama. Anda menekan CTRL-C untuk membatalkan apa yang sedang Anda lakukan. Anda akan menggunakan `CTRL- \` hanya sesekali untuk debugging untuk menghasilkan dump inti. Pada umumnya tidak ada alasan mengapa suatu aplikasi ingin menghalangi jalan Anda mencoba melakukan itu.
Stéphane Chazelas
@ StéphaneChazelas Tidak hanya kurang dan vim, sebagian besar aplikasi berbasis terminal yang membaca perintah pengguna untuk itu. Misalnya REPL (bash, dash, ksh, zsh, python, irb, fsharpi, Mathematica, ...). Ini hampir tidak biasa. Komentar pertama Anda menolak lukisan SIGINT dan SIGQUIT terlalu berbeda dan komentar terakhir Anda menganggap lukisan SIGINT dan SIGQUIT terlalu mirip, yang membuat saya bingung tentang apa yang Anda kendarai.
Gilles 'SANGAT berhenti menjadi jahat'
7

Selain jawaban Gilles izinkan saya menambahkan, bahwa Anda selalu dapat memasukkan karakter yang tidak dapat dicetak di bash dengan Ctrl-v+ key( Ctrl-v+ Ctrl+4dalam kasus ini) dan memeriksa kode karakter dengan

$ printf '^\' | od -An -tu    # input ^\ as C-v C-4
28

Anda mendapatkan kode desimal karakter, yang seperti Anda periksa man asciisesuai dengan pemisah file (FS) .

jimmij
sumber
Jadi apa yang dilakukan ctrl + v? Saya sudah terbiasa dengan itu "tempel clipboard".
JDługosz
2
@ JDługosz: Ctrl-V memberitahu terminal untuk tidak menafsirkan karakter berikut. Sangat disayangkan fakta bahwa kombinasi tombol GUI telah mengambil alih karakter kontrol tersebut, menyebabkan kebingungan yang tidak perlu. Dulu Linux menggunakan Alt- [Key] untuk kunci GUI (misalnya Alt-C / Alt / V untuk copy / paste), tetapi kemudian orang-orang jelas berpikir melakukan hal yang sama seperti Windows lebih penting; sementara itu pengguna Mac masih tidak memiliki masalah untuk menggunakan tombol Command daripada tombol Ctrl untuk operasi tersebut.
celtschk
Perintah (pendek) adalah: printf '%d\n' '"^\'?
Isaac