TIL: bash command tracing at function level
some-function () {
{ local -; set -x; } 2>/dev/null
some-command "$@"
}
{ local -; set -x; } 2>/dev/null enables set -x (command tracing/xtrace) for just this function, without leaking that setting to the caller.
As a result, some-command "$@" runs with full -x tracing visible (since the redirect only applies to the group, not to the rest of the function), and the moment the function returns, xtrace (and any other option) reverts to whatever the caller had. The debug tracing is scoped to just this one function, with no side effects on the rest of the script.
Breaking it down:
-
local -:localinside a function, given just-, saves the current shell option flags (everythingset -owould show) into a function-local scope. When the function returns, bash restores the shell options to whatever they were before the function was called.-is treated as a special variable name bylocalspecifically for this purpose. -
set -x: turns on xtrace, so every command executed afterward gets printed to stderr prefixed with+, showing exactly what’s running with expanded variables. This is normally a global, persistent setting. -
{ ... } 2>/dev/null: the group command wraps both statements so the2>/dev/nullapplies to both. This suppresses the trace output thatset -xitself would otherwise immediately produce (bash echoes theset -xcommand’s own invocation), and suppresses any noise fromlocal -. Without this redirect we would see stray+ local -/+ set -xlines in stderr before our actual tracing starts.