Script
#!/usr/bin/env bash # Exit on error. Append "|| true" if you expect an error. set -o errexit # Exit on error inside any functions or subshells. set -o errtrace # Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR set -o nounset # Catch the error in case mysqldump fails (but gzip succeeds) in `mysqldump |gzip` set -o pipefail # Turn on traces, useful while debugging but commented out by default set -o xtrace bash_backtrace() { echo TEST ls -l /proc/$$/fd >&2 } trap bash_backtrace ERR CMD="ls /does-not-exist" eval "${CMD}" > /tmp/foo exit Output
$ ./test.sh + trap bash_backtrace ERR + CMD='ls /does-not-exist' + eval 'ls /does-not-exist' ++ ls /does-not-exist ls: cannot access /does-not-exist: No such file or directory +++ bash_backtrace +++ echo TEST +++ ls -l /proc/19650/fd total 0 lrwx------. 1 sbarre sbarre 64 Apr 18 15:57 0 -> /dev/pts/0 l-wx------. 1 sbarre sbarre 64 Apr 18 15:57 1 -> /tmp/foo lrwx------. 1 sbarre sbarre 64 Apr 18 15:57 10 -> /dev/pts/0 lrwx------. 1 sbarre sbarre 64 Apr 18 15:57 2 -> /dev/pts/0 lr-x------. 1 sbarre sbarre 64 Apr 18 15:57 255 -> /home/sbarre/test.sh Because my eval is throwing an error and being caught by the trap, stdout is still pointing to /tmp/foo. So any echo's in my trap function will go to that file, instead of to the terminal.
How can I reset this safely in the trap function? I need to handle when the script itself is run in a way where its stdout is being redirected.
$ ./test.sh > log.txt I'd want to "fix" stdout back to log.txt from /tmp/foo