zshのstderrを除く他の場所から直接xtraceを出力する

zshのstderrを除く他の場所から直接xtraceを出力する

set -xset -o xtracezshから()のトレース出力をstderr以外のファイル記述子に送信できますか?

同等のものを探しています$BASH_XTRACEFDまたは同じ行動を模倣する方法です。

答え1

zsh 5.7以降、答えは「いいえ」です。トレース出力は常に stderr に送信されます。

ソース:ソースを読んでください。トレース出力はxtrerr有望と思われるファイルに書き込まれますが、唯一の割り当てはxtrerrto stderr、対応するコピー、またはtoですNULL

動的にロード可能なモジュール設定を作成することは可能ですxtrerrが、zshソースツリーの外側にモジュールを作成するのは簡単ではありません。

考えられる解決策の1つは、次のものを使用することxtraceです。DEBUG 。ほとんどの場合、これは同じ基本情報を提供しますが、xtrace完全にシミュレートするのは難しいか不可能な特別なケースがたくさんあると確信しています。 1つの違いは、オプションの継承と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サブシェルを開きます。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

そしてgenerate subshel​​lを使用してくださいTRACE_ZSH=1 zsh -l 2> debug.err.txt

関連情報