We can either use Bash's inbuilt debugging tools or write our scripts in such a manner that they become easy to debug; here's how:
- Add the -x option to enable debug tracing of a shell script.
$ bash -x script.sh
Running the script with the -x flag will print each source line with the current status.
- Debug only portions of the script using set -x and set +x. Consider this example:
#!/bin/bash
#Filename: debug.sh
for i in {1..6};
do
set -x
echo $i
set +x
done
echo "Script executed"
In the preceding script, the debug information for echo $i will only be printed, as debugging is restricted to that section using -x and +x.
The script uses the {start..end} construct to iterate from a start to end value, instead of the seq command used in the previous example. This construct is slightly faster than invoking the seq command.
- The aforementioned debugging methods are provided by Bash built-ins. They produce debugging information in a fixed format. In many cases, we need debugging information in our own format. We can define a _DEBUG environment variable to enable and disable debugging and generate messages in our own debugging style.
Look at the following example code:
#!/bin/bash
function DEBUG()
{
[ "$_DEBUG" == "on" ] && $@ || :
}
for i in {1..10}
do
DEBUG echo "I is $i"
done
Run the preceding script with debugging set to "on":
$ _DEBUG=on ./script.sh
We prefix DEBUG before every statement where debug information is to be printed. If _DEBUG=on is not passed to the script, debug information will not be printed. In Bash, the command : tells the shell to do nothing.