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-unknown-linux-gnu' -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -D_FORTIFY_SOURCE=2 -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector-strong --param=ssp-buffer-size=4 -DDEFAULT_PATH_VALUE='/usr/local/sbin:/usr/local/bin:/usr/bin' -DSTANDARD_UTILS_PATH='/usr/bin' -DSYS_BASHRC='/etc/bash.bashrc' -DSYS_BASH_LOGOUT='/etc/bash.bash_logout' uname output: Linux mirci 4.0.4-2-ARCH #1 SMP PREEMPT Fri May 22 03:05:23 UTC 2015 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu
Bash Version: 4.3
Patch Level: 39
Release Status: release
Description:
For lack of better terminology I call subshell introduced by pipeline
as implicit when written like this:
echo 'This will run in subshell' | cat
and explicit when written like this:
( echo 'This will run in subhshell' ) | cat
One would expect above snippets of code to be equivalent in function,
in second one parentheses are unnecessary, because pipeline will run
every part in subshell (unless "lastpipe" is set, which is of no interest
for us here).
I've observed that it's actually not true for traps, namely EXIT trap.
If EXIT trap is set in parent (main) shell, then this is inherited in
subshell in implicit case. It can be observed by running `trap` or `trap -p`
in subshell. This inherited trap is actually not executed on exit from
subshell. In explicit case, EXIT trap is rightly not inherited.
Going further, if subshell in implicit case will set it's own EXIT trap,
that one will not be executed, as oppose to explicit case where it executes.
As of writing this I've encountered also difference between the implicit
case
for simple command and a group command. See 2) in next section. I find that
strange also for the reason that $BASH_SUBSHELL evaluates to 0 when clearly
it is running inside subshell since $$ is different from $BASHPID.
Repeat-By:
1) implicit case with simple command
#!/bin/bash
trap 'echo EXIT-$$.$BASHPID.$BASH_SUBSHELL' EXIT
trap 'echo EXIT-$$.$BASHPID.$BASH_SUBSHELL' EXIT | cat
Output:
EXIT-8843.8843.0
2) implicit case with group command
#!/bin/bash
trap 'echo EXIT-$$.$BASHPID.$BASH_SUBSHELL' EXIT
{ trap 'echo EXIT-$$.$BASHPID.$BASH_SUBSHELL' EXIT; } | cat
Output:
EXIT-9136.9137.0
EXIT-9136.9136.0
3) explicit case
#!/bin/bash
trap 'echo EXIT-$$.$BASHPID.$BASH_SUBSHELL' EXIT
( trap 'echo EXIT-$$.$BASHPID.$BASH_SUBSHELL' EXIT ) | cat
Output:
EXIT-9189.9190.1
EXIT-9189.9189.0
Fix:
I haven't had a time to look at source but I expect that the fact that
EXIT trap from parent (main) shell is inherited in subshell (as listed
by `trap` — not shown in examples above) for 1) and 2) but rightly not
for 3) is indicative and probably right place to start looking. Maybe
fixing that would fix the rest. But that wouldn't explain difference
between 1) and 2) though.
I don't consider myself a Bash expert but, when I've raised this in #bash
on freenode we've concluded that it should be reported so I gather there
is something to it.
Best Regards,
Miro
--
Miroslav Koskar
http://mkoskar.com/
signature.asc
Description: PGP signature
