Чому Ctrl-C не вбиває сам термінал?


39

Термінал працює, коли ми його відкриваємо.

luvpreet@DHARI-Inspiron-3542:/$

Я щойно його відкрив. Отже, коли я натискаю Ctrl+ C, чому він не вбиває себе і закриває термінал ??


21
термінал не працює в терміналі ;-)
Pilot6

3
щодо того, чому працює контроль-d: unix.stackexchange.com/a/110248/14305
Janus Troelsen

Відповіді:


48

Ctrl+ C- сигнал переривання. Коли ви вводите це в терміналі, bash надсилає SIGINT на завдання на перший план. Якщо немає роботи (що буває, коли ви щойно відкрили термінал), нічого не відбувається. Програма термінального емулятора не є завданням, що працює в оболонці, тому вона не отримує сигнал і не закривається.

Якщо ви хочете закрити термінал за допомогою клавіші управління, використовуйте Ctrl+ D(EOF), що призводить до виходу bash (і закриває термінал теж).

Дивіться також: Посібник для початківців Bash щодо сигналів та більш глибоко, як працює подача сигналів
: ця відповідь була змінена з моменту публікації коментарів


4
Власний термін полягає в тому, що оболонка буде «захоплювати» сигнал. Інша історія - це коли ви запускаєте термінальне вікно з іншого вікна. Відправлення ctrl + c до батьківського вікна знищить дочірній процес.
Сергій Колодяжний

1
Крім того, вікна графічного інтерфейсу також можуть бути доручені захоплювати конкретні сигнали, що надходять з сервера X11. Ось так у вас можуть з’являтись спливаючі вікна, які сповіщають вас про незбережену роботу, або відкривати вкладки, як у браузерах
Сергій Колодяжний

8
@chrylis термінальна програма просто надсилає символ ctrl-c, це фактично шар ядра, який перетворює його в сигнал.
Випадково832

3
@chrylis: І термінал, або програма, що працює всередині нього - наприклад, текстовий редактор - цілком може перевести Ctl-C в якусь іншу дію.
jamesqf

3
Я не думаю, що bashпісля завершення натискання клавіш ctrl-c жодна програма не припинить. Він просто скаже ядро, яка група процесів активна, і ядро ​​генерує сигнал до цієї групи процесів, коли отримує ctrl-c від програми терміналу.
kasperd

32

^CНатискання клавіші, як і інші комбінації клавіш *, це не диво - він посилає код ключа в залежності від того , програма має фокус. (У X код коду дорівнює 54 для Cмодифікатора 0x4 для Ctrl.) Програма, яка отримує потік клавіш, відповідає за те, щоб зробити щось відповідне з ними - пам’ятайте, що у багатьох програмах GUI натискання клавіш копіюється у буфер обміну.

Коли емулятор терміналу GUI (наприклад, Konsole) або віртуальний термінал отримує натискання клавіші, яке він інтерпретує як ^C, він може зробити одну з трьох речей. Якщо термінал знаходиться в неочищеному режимі , то запущена програма попросила термінал не виконувати жодних оброблень спеціальних клавіш і не передавати їх прямо програмі. Деякі програми, що підтримують розширені функції, такі як редагування рядків, отримують введення на клавіатурі в деякій конфігурації між повними необробленими натисканнями клавіш та обробленими рядками тексту; bash, наприклад, отримує натискання клавіш по черзі. ^Cінтерпретується терміналом, але ключ зворотної області надсилається оболонці як є.

Більшість програм, однак, використовують приготовлений режим (тому що він не є сировиною), де термінал інтерпретує деякі основні натискання клавіш, перш ніж насправді надсилає їх програмі (саме тому ви можете використовувати зворотний простір в cat). У цьому режимі термінал сам переводить ^Cнатискання клавіші на SIGINTсигнал і передає його дочірньому процесу. Оскільки термінал генерував сигнал, він не заплутається і не припиниться.

  • SysRq насправді це магія.

Очевидно, що тут не надто актуально, але для загальних обчислень є більше магічних натискань клавіш. Найвідоміше - Ctrl+ Alt+ Deleteу світі Windows, де комбінація клавіш досить близька до магії (її можна використовувати для того, щоб Windows працював, що це досить магічно саме по собі!), Оскільки це важко закодовано в систему для переривання і перекрити майже все - досить схоже на SysRqте, що в цьому сенсі.
KRyan

7
Bash не використовує необроблений режим - він використовує режим символів, тобто cbreak/ -icanon, але він залишає встановлений isigрежим і отримує реальні сигнали при натисканні клавіш, нанесених на них. Він обробляє SIGINT, поводячись так, як ви описали (він не просто скасовує редагування рядків, він також скасовує будь-яку внутрішню команду, яка може працювати в циклі), і повністю ігнорує SIGTSTPі SIGQUIT. Інші програми, такі як vi, можуть не мати.
Випадково832

1
@KRyan Ctrl+ Alt+ Deleteраніше був навіть більш магічним, ніж сьогодні - blogs.msdn.microsoft.com/oldnewthing/20140912-00/?p=44083 . Незважаючи на те, що я є людиною Linux, я часто відчуваю страх за те, наскільки Windows в перші дні робив зручні та логічні речі з такими обмеженими ресурсами.
Музер

У деяких ОС, навіть якщо інша програма фокусується, система (я думаю, що менеджер вікон?) Насправді отримує натискання клавіш, перш ніж емулятор термінала коли-небудь зробить. Якщо ви можете налаштувати комбінації клавіш для оснащення вікон, відкриття програм, запуску скриптів, то перед натисканням клавіш надіслано емулятору терміналу, вони перевіряються на будь-які налаштовані ярлики. І інший приклад, якщо у вас немає відкритих додатків ^c, не вб'є менеджер вікон :). Не в змозі коментувати сирий / приготовлений персонаж за час роботи, але відповідь на місці про те, як генерується цей натискання клавішSIGINT
Ajay

2
" приготовлений режим (бо він не сирий)": я ... без мови. Після всіх цих років я жодного разу не зв’язувався.
isanae

8

^Cзазвичай відображається (див. stty -a) на SIGINTсигнал (див. man 7 signal).

Незловлений SIGINTперериває запущений процес, АЛЕ ...

SIGINT є одним із сигналів, для яких процес може вказати поведінку ("Ловля сигналу").

Те, що ви називаєте "терміналом", ловить SIGINT, і повертається до роботи.


7

Коли я був початківець, мені не вистачало тієї частини, що під час використання командного рядка я фактично використовував дві окремі програми, термінал і оболонку (наприклад, bash)

Оболонка - це те, що ви вже, напевно, знаєте, програма, яка приймає як вхідні команди чи сценарії, виконує їх та друкує свої результати.

Термінал з іншого боку - це як людина посередині між користувачем і програмою (яка програма, як правило, оболонка, як баш або риба). Що робить термінал, це читати вхід, наприклад, з клавіатури, можливо, обробляти цей вхід якимось чином і перенаправляти його на іншу програму (bash).

Також це працює і в інший спосіб, коли інша програма щось виводить, що щось перенаправляється до терміналу, тоді справа терміналу виводить щось на екран. Між отриманням введення та друком його на екран термінал може інтерпретувати вхід, який він отримує, різними способами.

Наприклад, якщо програма виводить таку послідовність:

\e[0;31m some extra foobar text

Термінал виведе на екран "якийсь додатковий текст фоабару" червоними кольоровими літерами. Це тому, що термінал обирає цей дивний код по-особливому, який натякає йому на друк наступного виводу червоним кольором.

Точно так само, коли користувач натискає Ctrl - C, єдине особливе в цьому полягає в тому, що термінал вирішує трактувати його особливим чином, нічого іншого особливого в цій послідовності ключів немає. Зокрема, це натякає на те, що він надсилає сигнал переривання (SIGINT) процесу, який працює всередині терміналу, тобто оболонці. Якщо в цей момент існує яка-небудь програма, породжена оболонкою і в даний час працює на передньому плані, вона також отримує сигнал. Тепер оболонка має спеціальний обробник цього сигналу, і нічого не відбувається. Але в більшості програм є обробники за замовчуванням, які у випадку SIGINT просто виходять.


5

Кожен сигнал має пов’язану з ним дію за замовчуванням. Дія за замовчуванням для сигналу - це дія, яку виконує сценарій або програма під час отримання сигналу.

Ctrl+ Cнадсилає сигнал "переривання" ( SIGINT ), який за замовчуванням припиняє процес завдання, що працює на передньому плані.

Ctrl+ Dповідомляє терміналу, що він повинен зареєструвати EOF на стандартному вході, що bash трактує як бажання вийти .

Процес може вибрати ігнорувати сигнал INT, і Bash робить це, коли він працює в інтерактивному режимі.

З посібника :

Коли bash є інтерактивним, за відсутності пасток він ігнорує SIGTERM (так, що kill 0 не вбиває інтерактивну оболонку), а SIGINT вловлюється та обробляється (щоб вбудований режим очікування був переривним). У всіх випадках баш ігнорує SIGQUIT. Якщо діє контроль за роботою, bash ігнорує SIGTTIN, SIGTTOU та SIGTSTP.


Зрозумійте це за допомогою пастки :

trap - це функція, вбудована в оболонку, яка реагує на апаратні сигнали та інші події. Він визначає та активує оброблювачі, які запускаються, коли оболонка отримує сигнали або інші особливі умови.

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

-l роздрукувати список назв сигналів та їх відповідні номери.
-pвідобразити команди пастки, пов'язані з кожним SIGNAL_SPEC.

arg слід читати та виконувати, коли оболонка отримує сигнальний сигнал. Кожен знак є або ім'ям сигналу, або номером сигналу. Імена сигналів нечутливі до регістру, а префікс SIG необов’язковий.

Якщо sigspec дорівнює 0 або EXIT , аргумент виконується при виході оболонки. Щоб зрозуміти це, закрийте термінал і відкрийте його після редагування наступного рядка у .bashrcфайлі.

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

Ctrl D аналогічний exitкоманді для виходу з терміналу.

Якщо ви бажаєте, щоб Bash вийшов після отримання сигналу INT, навіть в інтерактивному режимі, ви можете додати наступне до свого ~/.bashrc:

trap 'exit' INT

або

trap 'exit' 2

1
здається легітимним !!
лют.прем
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.