
コール スタックをデバッグし、echo
さまざまなファイルからステートメントを単純に出力しています。フラット ログは追跡するのが少し難しくなってきているので、出力をネストする最適な方法が何であるかを知りたいです。
STDOUT ストリームをオーバーロードできる場合、タブの数またはプレフィックスのスペース/タブ文字列のいずれかに環境変数を設定するのが最も簡単なオプションであると考えました。基本的に、STDOUT="$TABS$STDOUT"
出力ストリームの先頭にタブ文字を積み重ね続けるなどの操作を実行できれば便利です。
しかし、ストリームを上書きすることが可能かどうかはわかりませんでした。たとえば、すべての行の先頭にハイフンとスペースを付けたい場合、それは可能ですか?
そのような:
echo foo
echo bar
echo foobar
生産:
- foo
- bar
- foobar
- STDOUT のテンプレート化は可能ですか?
- 呼び出される可能性のあるさまざまなスクリプト内のすべての
echo
/ステートメントを変更することなく、出力をネストするための推奨方法は何ですか?printf
答え1
おそらく最も簡単な方法は、stdout と stderr をマージしても構わないのであれば、-x
フラグを付けて実行することです。このフラグは、各コマンドの実行時に、+++
ネスト レベルから文字数が決まるプレフィックスを付けて bash に各コマンドを出力させます。その後、出力を後処理して、プレフィックスを記憶しながら行を抑制し、プレフィックスのない後続の行に適用します。これが echo または printf になります。
たとえば、小さな階乗スクリプトを考えてみましょうmyprog
。
#!/bin/bash
f(){
local i=$1
if [[ "$i" > 1 ]]
then echo $((i*$(f $((i-1)))))
else echo $i
fi
echo "my debug info $i" >&2
}
echo "factorial ${1?} is $(f $1)"
実行すると
bash -x myprog 4 |&
awk '/^+/{ indent=$1; next }
{ print indent " " $0 }'
あなたにあげる
+++++ my debug info 1
++++ my debug info 2
+++ my debug info 3
++ my debug info 4
+ factorial 4 is 24
PS4
もちろん、を設定するだけで、行番号、ファイル名、関数を含む非常に優れたデバッグ出力を得ることができます-x
。例:
PS4='+ ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]} - [${SHLVL},${BASH_SUBSHELL}, $?] '
あなたにあげる:
++ myprog:10: main - [2,1, 0] f 4
++ myprog:3: f - [2,1, 0] local i=4
++ myprog:4: f - [2,1, 0] [[ 4 > 1 ]]
+++ myprog:5: f - [2,2, 0] f 3
+++ myprog:3: f - [2,2, 0] local i=3
+++ myprog:4: f - [2,2, 0] [[ 3 > 1 ]]
++++ myprog:5: f - [2,3, 0] f 2
++++ myprog:3: f - [2,3, 0] local i=2
++++ myprog:4: f - [2,3, 0] [[ 2 > 1 ]]
...