This is limited to Bash only, and the answer needs to work on all Bash versions without exception.
I do this now:
op1 (set -x; op2) op3
and it does what I expect: The op1 is not transcribed, the op2 is transcribed, and then op3 is not. And this has the feature that if “code wedging” occurs whereby op2 has a lot of lines of text, I do not have to remember to call set +x later on, because of the scoping with the parentheses. I do not want set +x to also get transcribed, either as it clutters up the output.
So, how do I do the above without having to explicitly call set +x? I’ve tried curly brackets but they don’t “undo” the set -x like the parentheses do.
Advertisement
Answer
Except in the case of modern bash 4.x with the off-by-default BASH_XTRACEFD feature in active use, the following will work fine:
logged_cmd() {
local rc=0
set -x
"$@"
{ { rc=$?; set +x; }; } 2>/dev/null
return "$rc"
}
op1
logged_cmd op2
op3
Adding support for cases where BASH_XTRACEFD is in use (to cause set -x logs to go somewhere other than stderr) will require using bash 4.1+ features, which has been explicitly disallowed in the question.