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
。