Bash 4.3.22, HP-UX.
imadev:~$ child() { trap - INT; trap 'echo I got an INT; trap - INT; kill -INT $
BASHPID' INT; while true; do sleep 1; done; }; child &
[1] 19116
imadev:~$ kill -INT 19116
imadev:~$ kill -INT 19116
imadev:~$ kill -TERM 19116
[1]+ Terminated child
The manual says:
Non-builtin commands run by bash have signal handlers set to the
values inherited by the shell from its parent. When job control is
not in effect, asynchronous commands ignore SIGINT and SIGQUIT in
addition to these inherited handlers.
And yes, turning on job control magically makes it work:
imadev:~$ child() { set -m; trap - INT; trap 'echo I got an INT; trap - INT; kil
l -INT $BASHPID' INT; while true; do sleep 1; done; }; child &
[1] 19127
imadev:~$ kill -INT 19127
imadev:~$ I got an INT
[1]+ Interrupt child
But I don't understand why job control is needed to override an inherited
(or automatically created) trap. Shouldn't an explicit trap always be
used?
Ksh (88) does not have this problem:
imadev:~$ ksh
$ child() { trap - INT; trap 'echo I got an INT; trap - INT; kill -INT
$BASHPID' INT; while true; do sleep 1; done; }; child &
[1] 19133
$ kill -INT 19133
$ I got an INT
child: kill: bad argument count
(Of course, ksh also doesn't have BASHPID, so ignore that last bit.)