.png)
bash スクリプトには、log()
複数の場所で使用される関数と、logs()
多くの行を に転送する関数がありますlog()
。 を含むスクリプトの一部を実行すると、当然のことながら、 とset -x
内のすべてのコマンドもトレースされます。logs()
log()
少なくともその内容、最良の場合はその呼び出しさえも出力から抑制されるように、 とlogs()
を定義したいと思います。log()
set -x
答え1
関数内から関数の呼び出し方法を変更することはできませんが、関数を定義してサブシェルを呼び出すことで、すぐにトレースをオフにすることができます。通常の中括弧ではなく、本体を囲む括弧に注意してください。
log() (
set +x
# rest of log()
)
呼び出すlog()
と、呼び出し自体 (既存のset -x
コードから) とset +x
呼び出しのみが生成され、関数内の後続のコマンドの残りは生成されません。set -x
関数が終了すると、既存の設定が復元されます。
答え2
すべてのシェルで機能する簡単なハックは、関数log
ではなく外部スクリプトを(一時的に)作成することです。
bash では、 よりもはるかに汎用性の高いtrap '...' DEBUG
と の組み合わせを使用することもできます。例:shopt -s extdebug
set -x
debug() {
local f=${FUNCNAME[1]} d=${#FUNCNAME[@]} c=$BASH_COMMAND
if [ "$NOTRACE" ]; then
case $debug_skip in ''|$d) debug_skip=;; *) return;; esac
eval "case \$c in $NOTRACE) debug_skip=\$d; return; esac"
fi
# before the 1st command in a function XXX
case $c in $f|"$f "*) return;; esac
printf >&2 "%*s(%s) %s\n" $((d * 2 - 4)) "" "$f" "$c"
}
(もちろん、奇妙なフォーマットとインデントを省いて完全にset-x
- のようにすることもできます。また、コマンドからの stderr と混合する代わりに、別のファイルにリダイレクトすることもできます。)
それから:
NOTRACE='"log "*'
shopt -s extdebug
trap debug DEBUG
log(){ log1 "$@"; }; log1(){ log2 "$@"; }
log2(){ log3 "$@"; }; log3(){ echo "$@"; }
foo(){ foo1 "$@"; }; foo1(){ foo2 "$@"; }
foo2(){ foo3 "$@"; }; foo3(){ echo "$@"; }
bar(){ case $# in 0) ;; *) echo "$1"; shift; bar "$@";; esac; }
foo 1 2 3
log 7 8 9
bar 1 2 3 4
結果は次のようになります:
(main) foo 1 2 3
(foo) foo1 "$@"
(foo1) foo2 "$@"
(foo2) foo3 "$@"
(foo3) echo "$@"
1 2 3
7 8 9
(main) bar 1 2 3 4
(bar) case $# in
(bar) echo "$1"
1
(bar) shift
(bar) case $# in
(bar) echo "$1"
2
(bar) shift
(bar) case $# in
(bar) echo "$1"
3
(bar) shift
(bar) case $# in
(bar) echo "$1"
4
(bar) shift
(bar) case $# in
答え3
xtrace 出力を抑制するには、 を使用しますset -x
。オンに戻すには、 を使用しますset -x
。オンになっているかどうかを確認するには、 を使用しますshopt -q -o xtrace
。例:
log() {
if shopt -q -o xtrace; then TRACE_IS_ON=yes; else TRACE_IS_ON=no; fi
set +x # turn xtrace off
...
[[ "$TRACE_IS_ON" == "yes" ]] && set +x
}
まだ多少の「チャタリング」はありますが、これが私ができる最善のことです。log() の呼び出しが表示されないようにするには、関数内ではなく、同様のコードを使用して log() の各呼び出しを囲みます。