Почему Ctrl-C не убивает сам терминал?


39

Терминал работает, когда мы его открываем.

luvpreet@DHARI-Inspiron-3542:/$

Я только что открыл его. Итак, когда я нажимаю Ctrl+ C, почему он не убивает себя и не закрывает терминал?


21
терминал не работает в терминале ;-)
Pilot6

3
относительно того, почему работает control-d: unix.stackexchange.com/a/110248/14305
Янус Троелсен,

Ответы:


48

Ctrl+ Cэто сигнал прерывания. Когда вы набираете это в терминале, bash отправляет SIGINT заданию на переднем плане. Если работы нет (как в случае, когда вы только что открыли терминал), ничего не происходит. Программа эмулятора терминала не работает в оболочке, поэтому она не получает сигнал и не закрывается.

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

См. Также: Руководство для начинающих Bash по сигналам и более подробно Как работает обработка сигналов,
обратите внимание: этот ответ был отредактирован с момента публикации комментариев


4
Правильный термин - это то, что оболочка будет «ловить» сигнал. Другая история - это когда вы запускаете окно терминала из другого окна. Отправка ctrl + c в родительское окно уничтожит дочерний процесс.
Сергей Колодяжный

1
Кроме того, окна GUI также могут инструктировать перехват определенных сигналов, поступающих с сервера X11. Таким образом, вы можете иметь всплывающие окна, уведомляющие вас о несохраненной работе, или открывать вкладки, как в браузерах
Сергей Колодяжный,

8
@chrylis терминальная программа просто отправляет символ ctrl-c, фактически слой ядра tty превращает его в сигнал.
Random832

3
@ chrylis: И терминал, или программа, работающая внутри него, например, текстовый редактор, вполне могут перевести Ctl-C в какое-то другое действие.
jamesqf

3
Я не думаю, bashчто завершит какие-либо программы, когда Ctrl-C нажата. Он просто сообщит ядру, какая группа процессов активна, и ядро ​​сгенерирует сигнал этой группе процессов, когда получит ctrl-c от терминальной программы.
Касперд

32

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

Когда эмулятор терминала с графическим интерфейсом (например, Konsole) или виртуальный терминал получает нажатие клавиши, которое он интерпретирует ^C, он может выполнить одну из трех вещей. Если терминал находится в необработанном режиме , то запущенная программа попросила терминал не выполнять какую-либо обработку самих специальных ключей и передавать их прямо в программу. Некоторые программы, которые поддерживают расширенные функции, такие как редактирование строк, получают ввод с клавиатуры в некоторой конфигурации между полными нажатиями клавиш и обработанными строками текста; bashНапример, получает нажатия клавиш по одному. ^Cинтерпретируется терминалом, но клавиша Backspace отправляется в оболочку как есть.

Большинство программ, однако, используют готовый режим (потому что он не является необработанным), когда терминал интерпретирует некоторые основные нажатия клавиш перед фактической отправкой их в программу (именно поэтому вы можете использовать backspace в cat). В этом режиме терминал сам переводит^C нажатие клавиши в SIGINTсигнал и отправляет его дочернему процессу. Поскольку терминал генерировал сигнал, он не запутается и не прекратит работу.

  • SysRq действительно волшебство

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

7
Bash не использует необработанный режим - он использует символьный режим, т. Е. cbreak/ -icanon, Но он оставляет установленный isigрежим и получает реальные сигналы при нажатии клавиш, которые сопоставлены с ними. Он SIGINTведет себя так, как вы описали (он не только отменяет редактирование строки, но и отменяет любую внутреннюю команду, которая может выполняться в цикле), и полностью игнорирует SIGTSTPи SIGQUIT. Другие программы, такие как vi, не могут.
Random832

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

На некоторых ОС, даже если другая программа фокусируется на системе (оконный менеджер, я полагаю?), Фактически получает нажатия клавиш раньше, чем когда-либо делает эмулятор терминала. Если вы можете настроить сочетания клавиш для привязки окон, открытия приложений, запуска сценариев, то перед отправкой нажатых клавиш в эмулятор терминала они проверяются на любые настроенные вами сочетания клавиш. И еще один пример, если у вас нет открытых приложений ^c, не убьет оконный менеджер :). Не в состоянии комментировать сырой / приготовленный персонаж одновременно, но SIGINT
Ajay

2
" приготовленный режим (потому что он не сырой)": я ... потерял дар речи. После всех этих лет я никогда не делал связь.
Исана

8

^Cобычно отображается (см. stty -a) на SIGINTсигнал (см.man 7 signal ).

Не пойман SIGINT прерывает процесс, НО ...

SIGINT является одним из сигналов, для которых процесс может указать поведение («перехват сигнала»).

То, что вы называете «терминалом», ловит SIGINTи возвращается к работе.


7

Когда я был новичком, мне не хватало того, что когда я использовал командную строку, я фактически использовал две отдельные программы, терминал и оболочку (например, bash).

Оболочка - это то, что вы, вероятно, уже знаете, программа, которая принимает в качестве входных команд или скриптов, выполняет их и печатает их вывод.

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

Также это работает и по-другому, когда другая программа выводит что-то, что-то перенаправляется на терминал, тогда работа терминала заключается в выводе этого чего-либо на экран. В промежутке между получением ввода и его печатью на экране терминал может интерпретировать вводимые данные различными способами.

Например, если программа выводит следующую последовательность:

\e[0;31m some extra foobar text

Терминал выведет на экран «какой-нибудь дополнительный текст для foobar» красными буквами. Это связано с тем, что терминал предпочитает обрабатывать этот странный код особым образом который намекает ему напечатать следующий вывод красным цветом.

Точно так же, когда пользователь нажимает Ctrl - C, единственное особенное в этом - это то, что терминал решает обрабатывать его особым образом, в этой последовательности клавиш нет ничего особенного. В частности, это намекает на отправку сигнала прерывания (SIGINT) процессу, который выполняется внутри терминала, то есть оболочки. Если в этот момент существует какая-либо программа, которая была порождена оболочкой и которая в данный момент работает на переднем плане, она также получает сигнал. Теперь в оболочке есть специальный обработчик для этого сигнала, и ничего не происходит. Но большинство программ имеют обработчики по умолчанию, которые в случае SIGINT просто завершаются.


5

С каждым сигналом связано действие по умолчанию. Действие по умолчанию для сигнала - это действие, которое скрипт или программа выполняет при получении сигнала.

Ctrl+ Cотправляет сигнал «прерывание» ( SIGINT ), который по умолчанию завершает процесс для задания, выполняемого на переднем плане.

Ctrl+ Dсообщает терминалу, что он должен зарегистрировать EOF на стандартном вводе, который bash интерпретирует как желание выйти .

Процесс может игнорировать сигнал INT, и Bash делает это, когда работает в интерактивном режиме.

Из руководства :

Когда bash является интерактивным, в отсутствие каких-либо ловушек он игнорирует SIGTERM (так что kill 0 не уничтожает интерактивную оболочку), а SIGINT перехватывается и обрабатывается (так, чтобы встроенная функция ожидания была прерываемой). Во всех случаях bash игнорирует SIGQUIT. Если контроль заданий действует, bash игнорирует SIGTTIN, SIGTTOU и SIGTSTP.


Пойми это с ловушкой :

trap - это встроенная в оболочку функция, которая реагирует на аппаратные сигналы и другие события. Он определяет и активирует обработчики, которые запускаются, когда оболочка получает сигналы или другие особые условия.

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

-l распечатать список имен сигналов и их соответствующих номеров.
-pотобразить команды прерывания, связанные с каждым SIGNAL_SPEC.

Аргументы должны быть прочитаны и выполнены, когда оболочка получает сигнал sigspec. Каждый sigspec является либо именем сигнала, либо номером сигнала. Имена сигналов нечувствительны к регистру, а префикс SIG является необязательным.

Если sigspec равен 0 или EXIT , arg выполняется при выходе из оболочки. Чтобы понять это, закройте терминал и откройте его после редактирования следующей строки в .bashrcфайле.

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

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

Если вы хотите, чтобы Bash выходил при получении сигнала INT, даже в интерактивном режиме, вы можете добавить следующее к вашему ~/.bashrc:

trap 'exit' INT

или

trap 'exit' 2

1
кажется законным !!
luv.preet
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.