Eu resolvi isso usando exec
para clonar as alças e restaurá-las na função de interceptação. Desta forma, não importa onde o STDERR esteja indo quando o script for iniciado, a saída da armadilha irá para lá também.
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
# Copy STDOUT and STDERR
exec 3>&1 4>&2
bash_backtrace() {
ls -l /proc/$$/fd >$(tty)
# Restore STDOUT and STDERR
exec 1>&3 2>&4
echo TEST
echo >&2 ERROR
ls -l /proc/$$/fd >&2
}
trap bash_backtrace ERR
CMD="ls /does-not-exist"
eval "${CMD}" > /tmp/foo 2> /tmp/bla
exit
Saída
+ exec
+ trap bash_backtrace ERR
+ CMD='ls /does-not-exist'
+ eval 'ls /does-not-exist'
total 0
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 0 -> /dev/pts/0
l-wx------. 1 sbarre sbarre 64 Apr 19 13:22 1 -> /tmp/foo
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 10 -> /dev/pts/0
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 11 -> /dev/pts/0
l-wx------. 1 sbarre sbarre 64 Apr 19 13:22 2 -> /tmp/bla
lr-x------. 1 sbarre sbarre 64 Apr 19 13:22 255 -> /home/sbarre/test.sh
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 3 -> /dev/pts/0
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 4 -> /dev/pts/0
+++ echo TEST
TEST
+++ echo ERROR
ERROR
+++ ls -l /proc/11910/fd
total 0
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 0 -> /dev/pts/0
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 1 -> /dev/pts/0
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 10 -> /dev/pts/0
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 11 -> /dev/pts/0
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 2 -> /dev/pts/0
lr-x------. 1 sbarre sbarre 64 Apr 19 13:22 255 -> /home/sbarre/test.sh
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 3 -> /dev/pts/0
lrwx------. 1 sbarre sbarre 64 Apr 19 13:22 4 -> /dev/pts/0