Skip to content
shellhacks.dev
Debugging

Trace only part of a script

Trace only the lines you are debugging by wrapping them in set -x and set +x. Write { set +x; } 2>/dev/null so the switch-off command is not traced itself.

1 min read
Summarize in AI

A trace of a whole script buries the three lines that matter under thousands of others.

Shell
echo before
set -x
x=$((1 + 2))
echo "x=$x"
{ set +x; } 2>/dev/null
echo after
Text
before
+ x=3
+ echo x=3
x=3
after

set -x prints each command after expansion to standard error, with the PS4 prefix, a plus sign by default, and set +x stops it. The trace only covers the lines between the two switches. The command that turns tracing off is itself traced, which would print an extra + set +x line, and putting it in a group whose standard error goes to /dev/null hides it. The option is described under the set builtin in the Bash manual.

Trace output goes to standard error, so it shows up in a log that captures both streams and in cron mail. It prints values after expansion, so a password in a variable is shown in the clear. In Bash 4.1 and later BASH_XTRACEFD sends the trace to another file descriptor, which keeps it out of the normal error output.

Share

More snippets

Debugging

Stop on the first error and show where

Report where a script failed with trap '...' ERR and set -E. LINENO gives the line, BASH_COMMAND the command and $? the status, even inside functions.

1 min read
Debugging

Print each line as it is read

Print every script line as the shell reads it, before expansion, with set -v. Pair it with set -x to see the source line and the expanded command.

1 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.