I am planning (well, have more or less implemented, but not committed) a small change to the way "sh -x" works, to cause the trace output (from -x) to continue appearing on the stderr that existed when the -x option was turned on - rather than following stderr around as the script alters it.
An example of the effect ... andromeda$ ENV=/dev/null PS4='+ ' sh -x /tmp/tst + exec 2>/dev/null andromeda$ ENV=/dev/null PS4='+ ' ./sh -x /tmp/tst + exec 2>/dev/null + test 0 -eq 1 + printf '%s\n' 'Usage: /tmp/tst log-file (with errors)' >&2 + exit 1 The ENV=/dev/null is just to avoid noise from my normal $ENV generating more output. /tmp/tst is a copy of an irrelevant script that is supposed to be run with one arg - when it isn't (as here) it prints a usage message and exits. I modified it by inserting "exec 2>/dev/null" right at the start of the script, which is why this demo uses a copy in /tmp instead of the original (which is not called "tst"...) The first invocation above (using "sh") is the old way. Once the exec command which moves stderr is performed, the tracing goes with it, so we see no more trace lines. The second ("./sh") is the new way, tracing continues on the stderr that the shell started with (as the -x option was turned on on the command line.) For this, stderr is remembered only when tracing turns from off to on, if it is on already, and another "set -x" is performed, nothing changes. That is deliberate, to avoid the trace output randomly moving around in scripts that have "set -x" in them, but are then run with -x on the command line (and similar effects). To change the destination of tracing, one needs to turn it off, then on again (eg: set +x -x 2>/tmp/newtrace). And yes, if tracing is off, "set -x 2>/tmp/trace-file" works as expected (tracing goes to the file in /tmp (in this example), the redirect is in effect only for the "set" command, so after that, "normal" stderr is unchanged.) Two questions. Does anyone have any objection to (or suggestions for) this? Would it be better to have this controlled by an option (perhaps -X ?) so users/scripts can use whichever method they prefer, and if so, what should the default setting be? kre ps: this only applies to "-x" output, not that from the (superficially similar) -v - mostly because (except when used as sh -nv script) I consider the -v option largely as a waste of time, and in that one case where it is useful, nothing actually gets executed (it is just a script syntax check) so stderr can't be changed.