Що CTRL + 4 (і CTRL + \) роблять в баші?


22

Я щойно випадково дізнався, що CTRL+ 4 закриває програми зчитування stdinвводу з командного рядка.

Ось як це виглядає, коли я набираю CTRL+ 4або CTRL+ / в програмах читанняstdin

$ 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
$

Я ^\Quitпоказую, а потім програма закривається. Чим відрізняється це порівняно з використанням ^Cабо ^D? Що робить ^\Quit?

Редагувати : Дізнався, що CTRL+ \робить те саме.

Відповіді:


37

Ctrl + 4 надсилає ^ \

Термінали надсилають символи (а точніше байти), а не ключі. Коли натискається клавіша, яка представляє символ для друку, термінал надсилає цього символу додатку. Більшість функціональних клавіш кодуються як послідовності втечі: послідовності символів, що починаються з символьної цифри 27. Деякі клавіатури форми Ctrl+ characterта кілька функціональних клавіш надсилаються як контрольні символи - в набір символів ASCII , який використовуються всі сучасні комп'ютери використовувати як основу (Unicode, ISO Latin- nі т. д. - це всі супернабори ASCII), 33 символи - це контрольні символи: символи від 0 до 31 та 127. Контрольні символи не друкуються, але призначені для ефекту в програмах; наприклад, символ 10, який є Control-J (зазвичай пишеться ^ J), є символом нового рядка, тому коли термінал відображає цей символ, він переміщує курсор до наступного рядка, а не відображає гліф. Сам символ втечі є керуючим символом, ^ [(значення 27).

Не вистачає символів управління, щоб охопити всі клавіатури Ctrl+ character. Лише букви та символи @[\]^_?мають відповідний контрольний символ. Коли ви натискаєте Ctrl+ 4або Ctrl+ $(я вважаю, що це Ctrl+ Shift+ 4), термінал повинен вибрати щось для надсилання. Залежно від терміналу та його конфігурації, існує кілька загальних можливостей:

  • Термінал ігнорує Ctrlмодифікатор і надсилає символ 4або $.
  • Термінал надсилає послідовність виходу, що кодує точну клавішу та модифікатори, які були натиснуті.
  • Термінал посилає якийсь інший керуючий символ.

Багато терміналів надсилають контрольні символи для деяких клавіш у цифровому рядку:

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

Я не знаю, де виникла ця конкретна конвенція.

Ctrl+ |надсилає той самий символ, тому що це Ctrl+ Shift+, \а термінал надсилає ^ \, натиснули чи ні клавішу зсуву.

^ \ виходить

Сам термінал (точніше, підтримка загального терміналу в ядрі) спеціально інтерпретує кілька контрольних символів. Ця інтерпретація може бути налаштована для відображення різних символів або відключена програмами, які хочуть обробити символів самостійно. Одне відоме таке тлумачення полягає в тому, що ^ M, символ, що надсилається Returnключем, посилає поточну лінію в додаток, якщо термінал знаходиться в приготовленому режимі , в якому програми отримують введення рядок за рядком.

Кілька символів передають сигнали програмі на перший план. ^ C посилає сигнал переривання (SIGINT), який умовно повідомляє програмі припинити, що вона робить, і прочитати наступну команду користувача. Неінтерактивні програми зазвичай виходять. ^ \ посилає сигнал виходу (SIGQUIT), який умовно повідомляє програмі якнайшвидше вийти, нічого не зберігаючи; багато програм не змінюють поведінку за замовчуванням, а це вбити програму негайно¹. Отже, коли ви натискаєте Ctrl+ 4(або що-небудь, що надсилає ^ \ символ) у catабо bc, жодне з яких не перекриває поведінку за замовчуванням, програма вбивається.

Сам термінал друкує ^\частину повідомлення: це візуальне зображення символу, який ви ввели, а термінал знаходиться в приготовленому режимі та з увімкненим відлунням (символи відображаються терміналом, як тільки ви їх набираєте, на відміну від неехо-режим, коли символи надсилаються лише програмі, яка може або не захоче їх відображати). QuitЧастина приходить з Баша: він зауважує , що процес його дитина померла від виходу сигналу, і це її спосіб дати вам знати.

Оболонки обробляють усі загальні сигнали, так що якщо ви введете ^ \ в оболонку, ви не вб'єте сеанс, ви просто отримаєте нове підказку, таке ж, як ^ C.

Ви можете грати з налаштуваннями терміналу за допомогою sttyкоманди.

¹ І традиційно генерують основний дамп , але сьогодні багато систем відключають це за замовчуванням.


SIGINT вбиває групу процесу переднього плану, а SIGQUIT вбиває її з основним дампам. Обидва сигнали можуть оброблятися. Я не впевнений, що ви маєте на увазі, читаючи наступну команду . Системи не вимикають базові скиди, крім встановлення початкового ліміту coredumpsize до 0 (не жорсткого, зазвичай ви можете підняти його).
Стефан Шазелас

@ StéphaneChazelas У програмі, яка виконує взаємодію з користувачем, звичайна семантика SIGINT полягає в тому, щоб скасувати поточну команду користувача та дозволити користувачеві взаємодіяти з програмою, тобто повернутися до основного циклу команд. З іншого боку, я не пам'ятаю, як бачив програму, де SIGQUIT не виходить (забороняючи помилки в обробці сигналів). Дійсно, як багато систем відключають базові дампи за замовчуванням, це встановити м'який обмеження розміру основного дампа на 0, а користувачі можуть змінювати цей параметр за замовчуванням, якщо вони бажають.
Жил "ТАК - перестань бути злим"

Це виняток. SIGINT вбиває поточне завдання. Лише кілька застосунків розширить це завдання, щоб знищити власне завдання "переднього плану". Ви повинні думати про lessабо vim. Зауважте, що в cmd | less, CTRL-Cяк правило , не вбиває cmd(тоді як для lessнього вирішується скасувати поточну дію (як пошук)) (продовження)
Stéphane Chazelas

Я вважаю формулювання вашої відповіді заплутаним у цьому плані. Те, що SIGQUIT, як правило, не обробляється, це те, що він не використовується однаково. Ви натискаєте CTRL-C, щоб скасувати те, що ви зараз робите. Ви використовуєте "CTRL- \" лише дуже періодично для налагодження для створення основного дампа. Як правило, немає причин, чому програма не хотіла б вам заважати, намагаючись це зробити.
Стефан Шазелас

@ StéphaneChazelas Не тільки менше і vim, більшість додатків на терміналі, які читають користувацькі команди на це. Наприклад, REPL (bash, dash, ksh, zsh, python, irb, fsharpi, Mathematica,…). Навряд чи рідкість. Ваш перший коментар заперечує малювання SIGINT та SIGQUIT як занадто різного, а ваш останній коментар об'єктів до малювання SIGINT та SIGQUIT як занадто схожий, що залишає мене спантеличеним щодо того, на що ви їдете.
Жил "ТАК - перестань бути злим"

7

На додаток до відповіді Гіллеса дозвольте додати, що ви завжди можете вводити символи, що не друкуються, у басі з Ctrl-v+ key( Ctrl-v+ Ctrl+4у цьому випадку) та перевіряти код символу за допомогою

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

ви отримуєте десятковий код символу, який, як ви можете перевірити, man asciiвідповідає роздільникам файлів (FS) .


Отже, що робить ctrl + v? Я звик до того, що це "вставити буфер обміну".
JDługosz

2
@ JDługosz: Ctrl-V повідомляє терміналу не інтерпретувати наступний символ. Прикро, що комбінації клавіш GUI перейняли ці контрольні символи, викликаючи непотрібне плутанину. Раніше Linux використовував Alt- [Key] для клавіш GUI (наприклад, Alt-C / Alt / V для копіювання / вставки), але тоді люди, очевидно, думали, що робити те саме, що Windows є важливішим; тим часом у користувачів Mac все ще немає проблем використовувати клавішу Command замість клавіші Ctrl для цих операцій.
celtschk

Команда (коротше) є: printf '%d\n' '"^\'?
Ісаак
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.