How do I trap SIGQUIT properly in a bash script?
I can write shell scripts that trap SIGINT
just fine, but I can't seem to trap 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
Executing this script and pressing CTRL-C
has the desired effect, but pressing CTRL-\
(which, as I understand, should trigger SIGQUIT
) does nothing except print ^\
in the terminal. Why?
I have two running theories. The first is that the semantics of SIGINT
and SIGQUIT
are different such that SIGQUIT
only gets sent to the child process sleep
, while SIGINT
gets sent to both the child process and the parent bash process. If this is the case, where is it documented?
My second theory is that bash not only ignores (i.e., has a no-op handler for) SIGQUIT
by default (as the man page suggests), but does not allow it to be trapped at all. This theory overlaps with the first theory, since it could be the case that SIGQUIT
is going to both parent and child, but the parent (bash
) just can't trap it. If this is the case, is there any way to trap SIGQUIT
in a bash script?... perhaps some shopt
I can set?
Edit: this is on Ubuntu 10.10 in gnome-terminal 2.32.0 running bash 4.1.5, and yes ^\
is configured to issue SIGQUIT (as reported by stty -a
and confirmed by issuing ^\
SIGQUITs to other programs like ping
).
UPDATE:
I just discovered that the problem must be due somehow to gnome-terminal. If I run this script from a virtual console (i.e., ctrl-alt-f1
to get out of X), it traps SIGQUIT perfectly fine when I press ^\
. Same bash and everything, so the only difference must be t开发者_如何学Gohe terminal emulator. So now my question becomes: how can I configure gnome-terminal to behave like the virtual console in this respect? I diff
'd the outputs of stty -a
in the virtual console and in gnome-terminal, and while there are differences, nothing seems immediately relevant (e.g., they both have quit = ^\;
).
UPDATE 2:
Another experiment. Simply execute $ sleep 60
in gnome-terminal; press ^\
and the signal goes uncaught. Now execute $ sleep 60
in the virtual console; press ^\
and the signal is caught -- the process prints Quit
and exits. But now run $ ping google.com
in gnome-terminal and press ^\
-- the signal is caught and handled as expected. So there is something weird about gnome-terminal such that SIGQUIT can be caught by some programs, but not by others, even if those other others do catch it when invoked from the virtual console. Perhaps I should just upgrade my gnome-terminal.
I can only assume that this was some sort of bug in gnome-terminal 2.32.0; I have since upgraded to Ubuntu 11.04, with gnome-terminal 2.32.1 (and bash 4.2.8) and SIGQUIT is now trapped as expected.
I observe the same behavior on Fedora 19 with XFCE: according to ps s
, bash in the xfce4-terminal has SIGQUIT ignored, running yes >/dev/null &
and then ps s
shows that even a subprocess has SIGQUIT ignored. When I (from the same terminal) run ssh localhost
, the shell in the ssh session also has SIGQUIT ignored, but yes >/dev/null &
has not.
Given the above comment which mentions gnome-terminal, I would guess the bug is in the common part of the two terminals: the vte
library. Mine is vte-0.28.2-9.fc19.x86_64
.
精彩评论