Discussion:
trap - inconsistent behaviour
Jeremy Townshend
2018-09-20 23:39:57 UTC
Permalink
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib -Wdate-time -D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/build/bash-vEMnMR/bash-4.4.18=. -fstack-protector-strong -Wformat -Werror=format-security -Wall -Wno-parentheses -Wno-format-security
uname output: Linux tower 4.15.0-32-generic #35-Ubuntu SMP Fri Aug 10 17:58:07 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 4.4
Patch Level: 19
Release Status: release

Description:
The behaviour of the "trap" builtin command changes merely by printing the
list of commands associated with each signal (trap command issued without
arguments).

Repeat-By:
Case 1: In a fresh terminal emulator issue the following:

( trap 'echo trapped >&2' HUP; { sleep 10 & sleepPID=$!; wait $sleepPID; } > >( sleep 1; kill -HUP $BASHPID; cat ) )

Case 2: Then in a fresh terminal emulator issue the following:

( trap 'echo trapped >&2' HUP; { sleep 10 & sleepPID=$!; wait $sleepPID; } > >( trap; sleep 1; kill -HUP $BASHPID; cat ) )

Expected outcome: either the trap is triggered in both cases or in neither
since the only difference is the additional trap command with no arguments
(for printing the list of commands associated with each signal). That is, in
this case, "trapped" is expected to be printed in both cases or in neither
case.

Actual outcome: the trap is not triggered in the first instance but is
triggered in the second.

Real use case: where zenity --progress --auto-kill is issuing the kill -HUP
as a result of the cancel button being pressed.
Chet Ramey
2018-09-21 12:17:45 UTC
Permalink
Post by Jeremy Townshend
Bash Version: 4.4
Patch Level: 19
Release Status: release
The behaviour of the "trap" builtin command changes merely by printing the
list of commands associated with each signal (trap command issued without
arguments).
( trap 'echo trapped >&2' HUP; { sleep 10 & sleepPID=$!; wait $sleepPID; } > >( sleep 1; kill -HUP $BASHPID; cat ) )
( trap 'echo trapped >&2' HUP; { sleep 10 & sleepPID=$!; wait $sleepPID; } > >( trap; sleep 1; kill -HUP $BASHPID; cat ) )
Expected outcome: either the trap is triggered in both cases or in neither
since the only difference is the additional trap command with no arguments
(for printing the list of commands associated with each signal). That is, in
this case, "trapped" is expected to be printed in both cases or in neither
case.
The trap command shouldn't be executed in either case. The process
substitution is executed in a subshell environment, which doesn't inherit
traps from its parent (though it inherits the trap strings; see
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_28).

The process substitution sends the SIGHUP to itself ($BASHPID), which
should cause it to terminate but not result in a signal being sent to its
parent. However, the parent is getting a SIGHUP from somewhere.

It seems like this behavior is the result of the shell being interactive.
I'll take a look.

Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://tiswww.cwru.edu/~chet/
Loading...