8

Please explain these trap outputs:

$ line(){ echo -------------; echo $BASHPID; }
$ trap 'echo bye' EXIT; trap -p; line; (trap -p; line); echo "$(trap -p; line)"

trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6176
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6178
trap -- 'echo bye' EXIT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
-------------
6180

Why does the command-substitution subshell behave differently in that that it claims to have inherited the trap dispositions (except that it doesn't actually follow them)?

2

Interesting. This appears to be Bash-specific behavior.

I tried 3 other POSIX-compatible shells (zsh, dash, busybox), and in all of them echo "$(trap)" gave the same result as (trap): a subshell is run, and the subshell does not show an EXIT trap.

(Note that trap -p is specific to Bash, and without extra parameters it does the same thing as trap with no parameters.)

Bash's behavior is potentially useful: it means you can write a="$(trap)" to capture the trap settings of the parent shell, which are more likely to be interesting.

However, if you set or clear a trap in the subshell, then it will list the subshell's traps instead of the parent's:

$ trap 'echo bye' EXIT
$ echo "$(trap TERM; trap)"  # explicitly clear TERM, but leave EXIT alone
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU

So they've also covered the rare case where you're interested in the subshell's traps.

In general, I've noticed that the Bash developers seem to have put some extra effort into making subshell handling work nicely. It's also a lot easier to manage background subprocesses with Bash than with the more minimal POSIX shells.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.