How to debug a bash script?

A script is just a file containing a set of commands. The basic idea of a script is to automatically execute and re-execute a series of commands instead of manually typing them one by one. For a script, all you require is to create a plain text file and enter a list of commands in order to achieve a specific task and then save the file. Now whenever you need to perform that specific task, simply execute the script file, and get the job done automatically.

This is the basic introduction of what a bash script is. Now let’s talk about script debugging. When we write a small script with few commands, then debugging them is merely like looking at the output and making sure they are working as expected. However, for larger scripts like scripts written for web pages, system configuration, etc, looking at just the output

is not enough to find the issues. This is where we require a debugging tool. When working with programming languages, there is a debugging tool integrated with them. However, in bash scripting, we do not have such a tool but we can make use of the command line to perform debugging.

In this article, we will learn how to debug a bash script in a Debian OS.

Following are some command-line debugging options available:

  • -x option – displays command traces prior to executing them
  • -n option – does not displays command just check for syntax errors
  • -v option – displays the commands while they are read

We are using Debian 10 OS for explaining the procedure discussed in this article.

Tracing the Execution ( -x option )

It instructs the shell to display how each command looks like before execution. Also, it gives you the choice whether to debug a whole script or just a part of it.

Debugging the Whole Script

Starting the shell with –x option will run the whole script in debugging mode. In this mode, traces of commands and their arguments are displayed to the output before they are executed.

This is our sample script named “myscript.sh”:

#!/bin/bash
exec 5> debug_output.txt
BASH_XTRACEFD="5"
PS4=‘$LINENO: ‘
var="Hello World!"
# print
echo "$var"
# alternative way to print
printf "%sn" "$var"
echo "My home is: $HOME"

To run the entire script in debug mode, add a -x parameter before the .sh command as follows:

$ bash -x ./script_name.sh

In our example, it would be:

$ bash -x ./myscript.sh

Below is our “myscript.sh” runs in debug mode. You can see that the added comments are not printed in the debugged output.

Debugging a Part of Script

If we are sure only a part of the script is causing errors, then there is no need to debug an entire script. We can debug some portion or several portions of the script as follows:

Place the “set –x” option at the starting point of the area that needs to debug and place the “set + x” option where you want it to stop. For instance, in the following script, we want to debug the area starting from $var because we think it is not working as expected. So we will enclose it by placing set –x option before the $ var line and end it by placing the set +x option at the second last line.

Edit the script file using any editor. We are using nano editor for this purpose:

$ sudo nano myscript.sh

Now enclose the area that you wish to debug using the set –x and set +x option as described above.

#!/bin/bash
exec 5> debug_output.txt
BASH_XTRACEFD="5"
PS4=‘$LINENO: ‘
set -x
var="Hello World"
# print
echo "$var"
# alternative way to print
printf "%sn" "$var"
set +x
echo "My home is: $HOME"

Once done, use Ctrl+O to save and then Ctrl+X to exit the file.

Then run the below command to execute the script:

$ ./myscript.sh

Now the output will look like this:

Disabling the Shell ( -n option)

-n (short for noexec or no execution) parameter enables the syntax checking mode. It instructs the shell to not execute the commands instead just check for the syntax errors. It a safe way to perform debugging as it does not execute the commands if they contain any error.

To run this mode, use the following syntax:

$ sh –n ./script_name

This is our sample script named “myscript1.sh”:

#!/bin/bash
var="Hello World"
echo "$var"
echo "My home directory is=$HOME
echo "
My username is=$USER"

When we run the script without any debugging option, it shows the following output:

To debug the script with –n parameter, the command would be:

$ sh -n ./myscript1.sh

You can see in the following output that it has not displayed any output but just the syntax errors.

Displaying the Scripts Commands ( -v option )

-v (short for verbose) instructs the shell to execute in verbose mode. When using this mode, it displays all commands in a script before executing them.

To run this mode, use the following syntax:

$ sh –v ./script_name

This is our sample script named “myscript1.sh:”

#!/bin/bash
var="Hello World"
echo "$var"
echo "My home directory is=$HOME
echo "
My username is=$USER"

This is what our script when we execute it without any debugging option:

Now when we execute it with –v parameter, it displays the following output. From the output, you can see that it has displayed the commands prior to their results.

That is it for now! We have seen how to debug a bash script using three different command line parameters. Among these parameters, –x parameter provides you with the choice to either debug a part of a script or an entire script.

Comments are closed, but trackbacks and pingbacks are open.