Seeing What Bash Sees
When a script behaves unexpectedly, the instinct is to scatter echo "I am here" statements throughout the code. There is a far more powerful approach built directly into Bash.
set -x (Execution tracing):
This tells Bash to print every command after variable expansion but before execution, each traced line prefixed with + (or ++ for commands inside subshells) — so if a variable was empty when it was expected to hold a value, the trace shows that empty expansion immediately, rather than leaving you to guess. It can be turned on for the whole script (as a header, or invoked via a flag without modifying the script at all) or scoped to just the section under suspicion by toggling it off again immediately after.
Customizing the trace prefix (PS4):
The default + prefix is not very informative in large scripts. Bash lets that prefix be redefined to include the source file, line number, and current function name — turning an anonymous stream of + lines into a trace that says exactly which file, which line, and which function produced each command, invaluable in scripts that source other scripts or call functions.
set -v (Verbose mode):
A related option, set -v, prints each line of the script before variable expansion. This is useful when you want to see the raw script text being executed, not the expanded values. Using both set -xv together gives you the raw line and the expanded command.
Key Point: Never leave set -x enabled in production scripts. The trace output can expose sensitive values (passwords, tokens) that appear in variables. Use it during development and debugging, then remove it. If you need permanent audit logging of what a script did, redirect the trace output to a log file: exec 2> /tmp/trace.log; set -x.
A common debugging scenario in interviews: "Your script works when you run it manually but fails in CI. How do you debug it?" The answer should mention bash -x script.sh to trace execution, checking environment variables (the CI environment may not have variables your local shell does), and set -euo pipefail to catch silent failures. Mentioning PS4 customization for line-number tracing signals genuine production experience.