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"
}
您无法更改从函数内部调用函数的方式,但您可以定义函数以调用子shell,然后立即关闭跟踪;注意主体周围的括号而不是典型的大括号:
然后调用
log()
仅生成调用本身(来自现有set -x
代码)和set +x
调用,而不是函数中的其余后续命令。一旦函数退出,现有set -x
设置就会恢复。应该适用于所有 shell 的快速而肮脏的 hack 是(暂时)使您
log
的外部脚本而不是函数。在 bash 中,您还可以使用 a
trap '...' DEBUG
andshopt -s extdebug
组合,它比set -x
. 例子:(当然,您可以省去奇怪的格式 + 缩进并使其完全
set-x
类似;您也可以将其重定向到另一个文件,而不是与命令中的 stderr 混合。)然后:
将导致:
要抑制 xtrace 输出,只需使用
set -x
. 要重新打开它,请使用set -x
. 要检测它是否打开,请使用shopt -q -o xtrace
. 例如仍然有一些“喋喋不休”,但这是我能做的最好的。要禁止看到对 log() 的调用,您可以使用类似的代码而不是在函数内部围绕对 log() 的每个调用。