In a bash shell in a terminal emulator window of lxterminal, I run
$ trap "echo hello" SIGHUP
$ kill -s HUP $$
hello
$
and then I close the terminal emulator window.
Does closing the terminal emulator window only cause SIGHUP sent to the controlling process i.e. the bash process?
Since the SIGHUP trap doesn't terminate the bash process, I expect the bash process isn't terminated, but why is the bash process actually terminated?
Same thing happen if I change the trap to ""
(ignore).
Terminal emulator matters. In bash running in a xterm window, setting trap to ""
will make a xterm window not closable, while setting trap to echo hello
can still close a xterm window.
Thanks.
Best Answer
[ I'll ignore the actual and possible behavior of different terminal emulators; a completely reasonable behavior would be to send a
^D
(VEOF
) to the pty on a window close /WM_DELETE_WINDOW
, instead of tearing it down and causing the process running in it to receive aSIGHUP
; the following assumesxterm
, which will send aSIGHUP
to the shell's process group in that case ].The behavior you're seeing is because of the
readline
library, which is installing its own signal handlers. If you try the following:(or
dash
,zsh
orksh
instead ofbash --noediting
), then runin the terminal, the window will become unclose-able; the shell will just print
HUP
as expected on trying to close the window; forcefully closing it (eg. withxkill
) will cause the shell to exit withEIO
errors, which is completely expected, since the pty was torn down.Here is a simpler testcase for the behavior you're observing, not involving terminal emulators. Run the following in your terminal:
Then
kill -HUP $$
will just printHUP
, but(sleep 1; kill -HUP $$) &
(orkill -HUP <pid>
from another window) will cause the shell to printexit
and exit, unless you started it with--noediting
(= don't use readline)The
readline()
function as called bybash
will install its own signal handlers upon waiting for input from the user, and restore the original handlers upon returning; aSIGHUP
while waiting for input from the user will cause it to returnNULL
, which will be treated asEOF
bybash
(in theyy_readline_get()
function), before having the chance to run the deferred trap handler.