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

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

luvpreet@DHARI-Inspiron-3542:/$

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

1
задан 8 March 2017 в 00:49

4 ответа

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

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

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

SysRq действительно волшебный.
31
ответ дан 23 May 2018 в 00:51
  • 1
    Очевидно, что здесь не очень важно, но для общих вычислений есть больше волшебных нажатий клавиш. Самый классный, Ctrl + Alt + Delete в мире Windows, где комбинация клавиш довольно близка к магии (его можно использовать, чтобы заставить Windows работать, это довольно волшебно и само по себе!), Поскольку он жестко закодирован в систему, чтобы прервать и переопределить почти все, что очень похоже на SysRq в этом смысле. – KRyan 7 March 2017 в 23:45
  • 2
    Bash не использует режим raw - он использует режим «по-разному», то есть cbreak / -icanon, но он оставляет установленный режим isig и принимает реальные сигналы при нажатии клавиш, которые отображаются на их. Он обрабатывает SIGINT, ведя себя, как вы описали (он не только отменяет редактирование строки, но также отменяет любую внутреннюю команду, которая может выполняться в цикле), и полностью игнорирует SIGTSTP и SIGQUIT. Другие программы, такие как vi, могут отсутствовать. – Random832 7 March 2017 в 23:55
  • 3
    @KRyan Ctrl + Alt + Delete был еще более волшебным, чем сегодня - blogs.msdn.microsoft.com/oldnewthing/20140912-00/?p=44083 . Хотя я человек Linux в глубине души, меня часто очень огорчает то, что Windows начала делать вещи удобными для пользователя и логичными с такими ограниченными ресурсами в первые дни. – Muzer 8 March 2017 в 14:25
  • 4
    На некоторых ОС, даже если другая программа имеет фокус, система (менеджер окон, я думаю?) Фактически получает нажатия клавиш до того, как эмулятор терминала когда-либо делает. Если вы можете настроить быстрые клавиши для привязки окон, откройте приложения, запускайте сценарии, а затем до нажатия нажатых клавиш на эмулятор терминала они будут проверены на наличие любых ярлыков, которые вы настроили. И еще один пример, если у вас нет приложений open ^c, не будет убивать оконный менеджер :). Невозможно прокомментировать сырой / приготовленный персонаж за раз, но ответ на вопрос о том, как это нажатие клавиши генерирует SIGINT – Ajay 8 March 2017 в 23:36
  • 5
    « приготовленный режим (потому что он не является сырым»): «Я ... потерял дар речи. После всех этих лет я никогда не связывал эту связь. – isanae 9 March 2017 в 11:50

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

Неиспользуемый SIGINT прерывает текущий процесс, BUT ...

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

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

7
ответ дан 23 May 2018 в 00:51

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

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

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

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

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

\e[0;31m some extra foobar text

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

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

6
ответ дан 23 May 2018 в 00:51

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

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

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

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

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

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

Понять это с помощью ловушки:

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

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

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

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

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

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

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

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

trap 'exit' INT

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

trap 'exit' 2
4
ответ дан 23 May 2018 в 00:51

Другие вопросы по тегам:

Похожие вопросы: