> On Wed, Apr 13, 2022 at 7:59 AM Frank Heckenbach > <f.heckenb...@fh-soft.de> wrote: > > This script writes "foo" to bar rather than stdout as I'd expect. > > > > It's triggered by the "if" statement (which doesn't even cause > > running in a subshell, so it's not that). > > > > #!/bin/bash > > set -e > > trap 'echo foo' 0 > > #false > bar # "foo" written to stdout correctly > > if true; then false; else false; fi > bar # "foo" written to bar > > I don't believe this is a bug, though Chet is welcome to chime in > with an authoritative answer. The script exits after the else clause > because false returns 1 and errexit is set. At this point in the program > stdout has been redirect to the file bar, so when the trap echos to > stdout its content goes to bar as well. I don't see anything in the > docs about traps resetting their output file descriptors before they > are ran.
I don't see anything to the contrary either. Syntactically, the redirection applies to the main statement, not the trap. When and how redirections are set up and reset is an implementation detail. Moreover, I don't see anything that would make a difference between the "if" statement and the plain one, so if the behaviour you describe is correct, the bug is that the non-"if" statement actually writes to stdout. :P > To work around this you need to save the original stdout file > descriptor. I know how to work around. But that makes me wonder. What is actually required to use a trap-statement safely (meaning, in a non-surprising way)? I know (for an EXIT trap) to save "$?" and "rethrow" it, now it seems one needs to save all FDs it might use (STDOUT, STDERR, maybe STDIN or other FDs one might redirect somewhere). What else is required? Is this documented anywhere?