Вопрос

Я могу писать сценарии оболочки, которые прекрасно перехватывают код SIGINT, но не могу перехватить код SIGQUIT.

родовое слово

Выполнение этого скрипта и нажатие CTRL-C дает желаемый эффект, но нажатие CTRL-\ (которое, как я понимаю, должно запускать SIGQUIT) ничего не делает, кроме печати ^\ в терминале. Почему?

У меня есть две актуальные теории. Во-первых, семантика SIGINT и SIGQUIT отличается, так что SIGQUIT отправляется только дочернему процессу sleep, а SIGINT отправляется как дочернему процессу, так и родительскому процессу bash. Если это так, где это задокументировано?

Моя вторая теория заключается в том, что bash по умолчанию не только игнорирует (т. е. не имеет обработчика для) SIGQUIT (как предлагается на странице руководства), но и не позволяет ему вообще быть перехваченным. Эта теория пересекается с первой теорией, поскольку может случиться так, что SIGQUIT будет передаваться как родительскому, так и дочернему, но родительский (bash) просто не может его перехватить. Если это так, есть ли какой-нибудь способ перехватить код SIGQUIT в сценарии bash? ... возможно, я могу установить какой-нибудь код shopt?

Изменить: это на Ubuntu 10.10 в gnome-terminal 2.32.0 с запущенным bash 4.1.5, и да, ^\ настроен на выдачу SIGQUIT (как сообщает stty -a и подтверждается выдачей SIGQUITs ^\ другим программам, таким как ping) <. / p>

ОБНОВЛЕНИЕ: Я только что обнаружил, что проблема должна быть каким-то образом связана с gnome-terminal. Если я запустил этот скрипт с виртуальной консоли (то есть, сгенерировал код для выхода из X), он отлично перехватит SIGQUIT, когда я нажму сгенерированный код. Тот же bash и все остальное, поэтому единственная разница должна заключаться в эмуляторе терминала. Итак, теперь мой вопрос таков: как я могу настроить gnome-terminal, чтобы он в этом отношении вел себя как виртуальная консоль? Я сгенерировал выходные данные ctrl-alt-f1 в виртуальной консоли и в gnome-terminal, и, хотя есть различия, ничего не кажется сразу актуальным (например, у них обоих есть ^\).

ОБНОВЛЕНИЕ 2: Еще один эксперимент. Просто выполните diff в gnome-terminal; нажмите кнопку stty -a, и сигнал не будет перехвачен. Теперь выполните в виртуальной консоли quit = ^\;; нажмите $ sleep 60 и сигнал будет пойман - процесс распечатает код ^\ и завершится. Но теперь запустите $ sleep 60 в gnome-terminal и нажмите ^\ - сигнал будет пойман и обработан, как ожидалось. Так что в gnome-terminal есть что-то странное, так что SIGQUIT может быть пойман одними программами, но не другими, даже если другие действительно поймают его при вызове с виртуальной консоли. Возможно, мне стоит просто обновить свой gnome-terminal.

Это было полезно?

Решение

Могу только предположить, что это была какая-то ошибка в gnome-terminal 2.32.0;С тех пор я обновился до Ubuntu 11.04 с gnome-terminal 2.32.1 (и bash 4.2.8), а SIGQUIT теперь заблокирован, как и ожидалось.

Другие советы

Я наблюдаю то же поведение в Fedora 19 с XFCE: согласно ps s, bash в xfce4-терминале игнорирует SIGQUIT, запускает yes >/dev/null &, а затем ps s показывает, что даже подпроцесс игнорирует SIGQUIT.Когда я (с того же терминала) запускаю ssh localhost, оболочка в сеансе ssh также игнорирует SIGQUIT, а yes >/dev/null & - нет.

Учитывая приведенный выше комментарий, в котором упоминается gnome-terminal, я предполагаю, что ошибка находится в общей части двух терминалов: в библиотеке vte.Мой код генерирует код.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top