Bash Script Debugging is a must-have skill for Linux users, sysadmins, and developers. Scripts often fail silently, leaving you frustrated. With the right debugging tools and techniques, you can spot syntax errors, track variables, and fix issues faster.
This guide explores the most effective Bash Script Debugging methods, including built-in options, error detection flags, and real-world debugging examples. By the end, you’ll know how to debug scripts like a pro.
Table of Contents
Why Bash Script Debugging Matters
When a Bash script fails, it rarely provides detailed error messages. Debugging helps you trace execution, catch typos, and monitor variable values. Without it, troubleshooting can take hours.
Proper debugging not only saves time but also improves script reliability. Whether you’re automating tasks or managing servers, Bash debugging ensures fewer surprises in production.
Bash Debugging Options You Should Know
Bash offers multiple built-in options for debugging. Let’s break them down with examples.
1. The -x
Option: Trace Commands
The -x
flag lets you run a script in tracing mode. Every command is printed before execution, showing variable substitutions and logic flow.
bash -x script.sh
Example:
a=5
b=10
echo $((a + b))
Output with tracing:
+ a=5
+ b=10
+ echo 15
15
This helps you follow the script step-by-step, just like reading a live execution log.
2. The -n
Option: Syntax Check
The -n
flag checks syntax without executing commands. It’s like a grammar checker for your script.
bash -n script.sh
Example with error:
if [ $a -gt 5 ]
echo "a is greater than 5"
fi
Output:
syntax error near unexpected token 'echo'
This is invaluable before running scripts in production.
3. The -u
Option: Unbound Variable Detection
The -u
flag (or set -u
) raises an error when referencing undefined variables. This prevents silent failures.
#!/bin/bash
set -u
echo "Value: $unassigned_variable"
Output:
unbound variable error
This protects you from typos or forgotten variable initializations.
4. The -v
Option: Verbose Mode
The -v
flag prints each line before executing it. Unlike -x
, it doesn’t show substitutions but reveals raw script flow.
bash -v script.sh
It’s useful for spotting missing keywords or misaligned logic.
5. Combining Debugging Flags
You can combine debugging options for maximum visibility. For example:
bash -xv script.sh
Here, -v
shows raw lines, while -x
shows expanded commands. This combination helps trace scripts in detail.
Debugging with set
Command
Instead of launching scripts with flags, you can enable debugging inside the script using set
.
set -x
→ Enable tracing mode.set +x
→ Disable tracing mode.set -u
→ Enable unbound variable detection.
Example:
#!/bin/bash
set -u
set -x
a=10
echo "PID: $$"
set +x
b=20 # Not traced
set -x
echo "a + b + c = $((a + b + c))"
Here, tracing pauses when unnecessary and resumes later for critical parts.
Practical Debugging Techniques
Sometimes flags alone aren’t enough. Here are practical methods to catch tricky errors.
Echo Statements
Placing echo
statements inside scripts helps track variable values and execution progress. Example:
echo "Step 1 completed. Value of a=$a"
It’s a simple yet effective manual debugging technique.
Using tee
for Logs
The tee
command logs intermediate output while keeping execution intact.
command | tee debug_log.txt
This allows you to review logs after execution, which is helpful in long-running scripts.
Redirecting Errors
You can redirect standard error (stderr) for debugging.
script.sh 2> error.log
This ensures you don’t miss silent errors buried in terminal output.
Real-World Debugging Examples
Let’s look at real-world use cases where Bash Script Debugging saves the day.
Example 1: Detecting Typos in Variables
#!/bin/bash
set -u
username="admin"
echo "User: $usename"
Error:
unbound variable error
This catches misspelled variables instantly.
Example 2: Debugging Loops
#!/bin/bash
set -x
for i in {1..3}; do
echo "Iteration $i"
done
Trace Output:
+ for i in {1..3}
+ echo 'Iteration 1'
Iteration 1
...
This confirms loop behavior is correct.
Example 3: Debugging File Operations
#!/bin/bash
set -x
cp /nonexistent/file.txt /tmp/
Error:
cp: cannot stat '/nonexistent/file.txt': No such file or directory
Here, debugging confirms the issue lies in the missing source file.
Key Takeaways
-x
shows expanded command execution.-n
checks syntax errors before execution.-u
detects unset variables.-v
reveals raw script lines.set
lets you toggle debugging inside scripts.- echo, tee, and stderr redirection provide extra insights.
By mastering these methods, Bash Script Debugging becomes faster and more reliable.
FAQ: Bash Script Debugging
Q1. What is the best option for Bash Script Debugging?
The -x
option is the most commonly used because it traces commands and variable values step by step.
Q2. How do I check syntax without running a Bash script?
Use bash -n script.sh
. It scans for syntax errors without executing any commands.
Q3. Can I debug specific parts of a Bash script?
Yes, by using set -x
and set +x
around critical sections, you can enable or disable tracing selectively.
Q4. How do I catch unset variables in Bash?
Enable strict mode with set -u
to throw errors whenever unbound variables are used.
Q5. What’s the difference between -x
and -v
in debugging?
-v
prints raw script lines, while -x
shows expanded commands with variable values. Combining both gives deeper visibility.