Я могу написать сценарии оболочки, которые просто перехватывают SIGINT
, но я не могу перехватить SIGQUIT
.
#!/bin/bash
function die {
echo "Dying on signal $1"
exit 0
}
trap 'die "SIGINT"' SIGINT
trap 'die "SIGQUIT"' SIGQUIT
while true; do
echo "sleeping..."
sleep 5
done
Выполнение этого сценария и нажатие CTRL-C
дает желаемый эффект,но нажатие CTRL-\
(которое, как я понимаю, должно вызвать SIGQUIT
) ничего не делает, кроме печати ^\
в терминале.Почему?
У меня есть две действующие теории.Во-первых, семантика SIGINT
и SIGQUIT
отличается тем, что SIGQUIT
отправляется только дочернему процессу sleep
, тогда как SIGINT
отправляется как дочернему процессу, так и родительскому процессу bash.Если это так, то где это задокументировано?
Моя вторая теория заключается в том, что bash не только игнорирует (т. Е. Имеет неработающий обработчик для) SIGQUIT
по умолчанию (как предполагает страница man),но не позволяет ему быть пойманным в ловушку вообще.Эта теория пересекается с первой теорией, так как может быть так, что SIGQUIT
направляется как к родителю, так и к ребенку, но родитель (bash
) просто не может ее перехватить.Если это так, есть ли любой способ перехвата SIGQUIT
в скрипте bash? ... возможно, какой-нибудь shopt
, который я могу установить?
Редактировать: это на Ubuntu10.10 в gnome-Terminal 2.32.0 работает Bash 4.1.5, и да ^\
настроен на выдачу SIGQUIT (как сообщается stty -a
и подтверждается путем выдачи ^\
SIGQUIT для других программ, таких как ping
).
ОБНОВЛЕНИЕ: Я только что обнаружил, что проблема должна быть как-то из-за gnome-терминала.Если я запускаю этот скрипт с виртуальной консоли (то есть ctrl-alt-f1
, чтобы выйти из X), он прекрасно перехватывает SIGQUIT, когда я нажимаю ^\
.Тот же bash и все, поэтому единственное отличие должно быть эмулятором терминала.Итак, теперь у меня возникает вопрос: как я могу настроить gnome-терминал, чтобы он вел себя как виртуальная консоль в этом отношении?Я diff
сделал вывод stty -a
в виртуальной консоли и в gnome-терминале, и, хотя есть различия, ничто не кажется актуальным (например, они оба имеют quit = ^\;
).
ОБНОВЛЕНИЕ2: другой эксперимент.Просто выполните $ sleep 60
в gnome-терминал;нажмите ^\
и сигнал останется необработанным.Теперь выполните $ sleep 60
в виртуальной консоли;нажмите ^\
и сигнал будет перехвачен - процесс напечатает Quit
и выйдет.Но теперь запустите $ ping google.com
в gnome-терминал и нажмите ^\
- сигнал перехватывается и обрабатывается, как и ожидалось.Так что в gnome-terminal есть что-то странное, так что SIGQUIT может быть перехвачен некоторыми программами, но не другими, даже если другие do перехватят его при вызове из виртуальной консоли.Возможно, я должен просто обновить свой gnome-терминал.