STDOUT をテンプレート化/上書きすることは可能ですか?

STDOUT をテンプレート化/上書きすることは可能ですか?

コール スタックをデバッグし、echoさまざまなファイルからステートメントを単純に出力しています。フラット ログは追跡するのが少し難しくなってきているので、出力をネストする最適な方法が何であるかを知りたいです。

STDOUT ストリームをオーバーロードできる場合、タブの数またはプレフィックスのスペース/タブ文字列のいずれかに環境変数を設定するのが最も簡単なオプションであると考えました。基本的に、STDOUT="$TABS$STDOUT"出力ストリームの先頭にタブ文字を積み重ね続けるなどの操作を実行できれば便利です。

しかし、ストリームを上書きすることが可能かどうかはわかりませんでした。たとえば、すべての行の先頭にハイフンとスペースを付けたい場合、それは可能ですか?

そのような:

echo foo
echo bar
echo foobar

生産:

- foo
- bar
- foobar

  1. STDOUT のテンプレート化は可能ですか?
  2. 呼び出される可能性のあるさまざまなスクリプト内のすべての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 ]]
...

関連情報