Direct xtrace output elsewhere than stderr in zsh

debuggingzsh

In zsh, is it possible to direct the trace output from set -x (set -o xtrace) to a file descriptor other than stderr?

I'm looking for an equivalent of $BASH_XTRACEFD or a way to emulate the same behaviour.

Best Answer

As of zsh 5.7, the answer is no. The trace output always goes to stderr.

Source: reading the source. The trace output is written to the file xtrerr, which looks promising, but the only assignments to xtrerr are to stderr, to a copy of it, or to NULL.

It should be possible to write a dynamically loadable module that sets xtrerr, but writing a module outside the zsh source tree is not easy.

A possible workaround is to emulate xtrace with a DEBUG trap. This provides the same basic information in most cases, but I'm sure there are plenty of corner cases where xtrace would be hard or impossible to emulate perfectly. One difference is that the inheritance of the xtrace option and the inheritance of traps follow different rules in some circumstances related to functions, subshells, emulate, etc. Proof-of-concept:

trap 'print -r -- "+$0:$LINENO>$ZSH_DEBUG_CMD" >>trace_file' DEBUG

Or maybe a bit more sophisticated (untested):

zmodload zsh/system
sysopen -a -o create -u xtrace_fd trace_file
trap 'syswrite -o $xtrace_fd "+$0:$LINENO>$ZSH_DEBUG_CMD"' DEBUG
Related Question