在 zsh 中除 stderr 之外的其他地方直接 xtrace 输出

在 zsh 中除 stderr 之外的其他地方直接 xtrace 输出

set -x在 zsh 中,是否可以将( )的跟踪输出定向set -o xtrace​​到 stderr 之外的文件描述符?

我正在寻找相当于$BASH_XTRACEFD或模仿相同行为的方法。

答案1

从 zsh 5.7 开始,答案是否定的。跟踪输出始终发送至 stderr。

来源:阅读来源。跟踪输出写入文件xtrerr,这看起来很有希望,但对 的唯一分配xtrerr是 to stderr、其副本或 to NULL

应该可以编写一个设置 的动态可加载模块xtrerr,但是在 zsh 源代码树之外编写模块并不容易。

一种可能的解决方法是xtrace使用DEBUG 陷阱。在大多数情况下,这提供了相同的基本信息,但我确信有很多极端情况xtrace很难或不可能完美模拟。一个区别是,在某些与函数、子 shell 等相关的情况下,选项的继承xtrace和陷阱的继承遵循不同的规则。emulate概念验证:

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

或者也许更复杂一点(未经测试):

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

答案2

我正在使用一个非常简单的解决方法,如果您只想调试特定的函数,该解决方法可能会很有用,尽管可以将相同的想法应用于完整的跟踪set -x

当我需要调试特定功能时,例如myfunc,我打开一个子 shell,TRACE_FUNC=myfunc zsh -l 2> debug.err.txt同时我已经设置了~/.zshrc以下内容:

if [ -n "${TRACE_FUNC}" ]; then
    functions -t "$TRACE_FUNC"
fi

您可以通过输入~/.zshrc以下内容来应用相同的想法:

if [ -n "${TRACE_ZSH}" ]; then
    set -x
fi

并使用 生成子 shell TRACE_ZSH=1 zsh -l 2> debug.err.txt

相关内容