2024-09-02 16:42:08 -06:00
# Script Debugging Techniques
## 1. Enable debugging mode
The first step in debugging a bash script is to enable debugging mode. You can do this in two ways:
- Add the -x option when running the script:
2024-09-07 10:14:32 -06:00
```
2024-09-02 16:42:08 -06:00
bash -x your_script.sh
```
- Add the set -x command at the beginning of your script:
2024-09-07 10:14:32 -06:00
```
2024-09-02 16:42:08 -06:00
#!/bin/bash
set -x
# Rest of your script
```
The -x option enables trace debugging, which prints each command and its arguments as they are executed.
## 2. Use set options for additional debugging
Bash provides several set options that can help with debugging:
2024-09-07 10:14:32 -06:00
- `set -e` : Exit immediately if a command exits with a non-zero status.
- `set -u` : Treat unset variables as an error when substituting.
- `set -o` pipefail: The return value of a pipeline is the status of the last command to exit with a non-zero status.
2024-09-02 16:42:08 -06:00
You can combine these options:
2024-09-07 10:14:32 -06:00
```
2024-09-02 16:42:08 -06:00
#!/bin/bash
set -euo pipefail
set -x
# Rest of your script
```
## 3. Add echo statements
Insert echo statements throughout your script to print variable values or to indicate which part of the script is being executed:
2024-09-07 10:14:32 -06:00
```
2024-09-02 16:42:08 -06:00
echo "Debug: Variable value is $variable"
echo "Debug: Entering function foo"
```
## 4. Use bash's built-in debugging commands
Bash provides several built-in commands for debugging:
2024-09-07 10:14:32 -06:00
- `set -v` : Prints shell input lines as they are read.
2024-09-02 16:42:08 -06:00
- trap: Can be used to debug functions or specific parts of your script.
Example of using trap:
2024-09-07 10:14:32 -06:00
```
2024-09-02 16:42:08 -06:00
trap 'echo "Line $LINENO: Command \\"$BASH_COMMAND\\" exited with status $?"' ERR
```
## 5. Use a debugger
For more complex scripts, you might want to use a debugger. Bashdb is a popular bash script debugger. Here's how to use it:
a) Install bashdb (on Ubuntu/Debian):
2024-09-07 10:14:32 -06:00
`sudo apt-get install bashdb`
2024-09-02 16:42:08 -06:00
b) Run your script with bashdb:
2024-09-07 10:14:32 -06:00
`bashdb your_script.sh`
2024-09-02 16:42:08 -06:00
This will start an interactive debugging session where you can set breakpoints, step through the code, and inspect variables.
## 6. Check for syntax errors
Before diving into debugging, check for syntax errors:
2024-09-07 10:14:32 -06:00
`bash -n your_script.sh`
2024-09-02 16:42:08 -06:00
This will check for syntax errors without executing the script.
## 7. Use shellcheck
Shellcheck is a static analysis tool for shell scripts. It can catch common errors and suggest improvements:
a) Install shellcheck (on Ubuntu/Debian):
2024-09-07 10:14:32 -06:00
`sudo apt-get install shellcheck`
2024-09-02 16:42:08 -06:00
b) Run shellcheck on your script:
2024-09-07 10:14:32 -06:00
`shellcheck your_script.sh`
2024-09-02 16:42:08 -06:00
## 8. Debug specific sections
If you only want to debug a specific section of your script, you can use set -x and set +x to turn debugging on and off:
2024-09-07 10:14:32 -06:00
```
2024-09-02 16:42:08 -06:00
#!/bin/bash
# Normal execution
echo "This part is not debugged"
# Start debugging
set -x
echo "This part is debugged"
# Stop debugging
set +x
echo "Back to normal execution"
```
## 9. Use PS4 for more informative debug output
You can customize the prefix used for debug output using the PS4 variable:
2024-09-07 10:14:32 -06:00
```
2024-09-02 16:42:08 -06:00
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
set -x
# Your script here
```
This will prefix each debug line with the source file, line number, and function name.
## 10. Check exit status
After each important command, check its exit status:
2024-09-07 10:14:32 -06:00
```
2024-09-02 16:42:08 -06:00
important_command
if [ $? -ne 0 ]; then
2024-09-07 10:14:32 -06:00
echo "Error: important_command failed"
exit 1
2024-09-02 16:42:08 -06:00
fi
```
## 11. Use bash's DEBUG trap
You can use the DEBUG trap to execute a command before each command in your script:
2024-09-07 10:14:32 -06:00
`trap 'echo "About to execute: $BASH_COMMAND"' DEBUG`
2024-09-02 16:42:08 -06:00
This will print each command before it's executed.
By combining these techniques, you can effectively debug your bash scripts and identify issues more quickly. Remember to remove or comment out debugging code before using the script in production.