I see that many questions have been asked and answered on SE about redirections in Bash using exec, but none seem to answer my question.
What I'm trying to accomplish is redirect all output to stderr in a script to a temporary fd and restitute it back to stderr only in case of non-successful script termination. The ability to restore the contents of stderr is needed in case of a non-successful termination, for returning to the caller information about the error. Redirecting stderr to
/dev/null would discard both irrelevant noise and useful information. As much as possible, explicit temporary files should be avoided, as they add a number of other issues (see https://dev.to/philgibbs/avoiding-temporary-files-in-shell-scripts). The contents of stdout should be returned transparently to the caller. It will be ignored by the caller in case of non-successful termination of the script, but the script shouldn't need to care about that.
The reason for doing this is that the script is called from another program that considers any output to stderr an error, instead of testing for a non-zero exit code. In the example below, openssl echoes a progress indicator to stderr which does not indicate an error and can be ignored upon successful completion of the command.
Below is a simplified version of my script (note that openssl here is only a placeholder for arbitrary and possibly more complex instructions):
#!/bin/bash set -euo pipefail # Redirect stderr to temp fd 3 exec 3>&2 # In case of error, copy contents of fd 3 to stderr trap 'cat <&3 >&2' ERR # Upon exit, restore original stderr and close fd 3 trap 'exec 2>&3 3>&-' EXIT # This nonetheless outputs the progress indicator to stderr openssl genpkey -algorithm RSA
But I'm obviously missing something as the script keeps printing out the content of stderr upon successful termination, but now blocks upon failure. I guess I'm confused with how redirections with exec work. What am I getting wrong?