Bash Advanced Trap on Debug
Advanced DEBUG tracing shows each command before it runs, using the command's own source text. It turns a silent section into a visible step list.
A DEBUG trap prints each command before it runs
The trap reads BASH_COMMAND before each command. Each trace line shows the source text as written.
trace() { echo "TRACE: $BASH_COMMAND"; }
trap trace DEBUG
x=2
y=$((x * 3))
echo "result $y"
trap - DEBUG
echo "after"xtrace shows expanded values, not source text
PS4 sets the trace prefix, and BASH_XTRACEFD sends traces to stdout. The trace shows 5, the value after expansion, not the expression.
exec 5>&1
export PS4='+ line $LINENO: '
BASH_XTRACEFD=5
set -x
a=4
b=$((a + 1))
echo "sum $b"
set +x
echo "done"By default, a DEBUG trap skips function bodies
The trap fires for the call to work, but not for the commands inside it. The body still runs; it just runs untraced.
trace() { echo "TRACE: $BASH_COMMAND"; }
trap trace DEBUG
work() {
v=10
echo "inside $v"
}
work
trap - DEBUG
echo "final"Example
trace() { echo "TRACE: $BASH_COMMAND"; }
trap trace DEBUG
price=12
count=3
total=$((price * count))
echo "total $total"
trap - DEBUG
echo "report done"Key points
- BASH_COMMAND: the source text of the command about to run, read inside the trap.
- Unexpanded text: the trap shows a variable as written, not its value.
- PS4: the prefix printed before each xtrace line; it can carry a line number.
- BASH_XTRACEFD: the file descriptor xtrace writes to; point it at a copy of stdout to keep traces in order.
- Function limit: a DEBUG trap does not fire inside a function body unless functrace is on.
- Scope: set the trap, run one section, then remove it with trap - DEBUG.
- Removal echo: the trap fires once for its own removal command.
In this example, a trace function prints BASH_COMMAND before each command. The trap is set before the price section, so it labels the price, count, and total commands, plus the echo that prints the total. The trap is then removed, so the final line prints with one last trace for the removal command itself and no label after it.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
A DEBUG trap prints BASH_COMMAND for echo "total $total". What does the trace line show?