How do I debug a bash script?

A script is simply a file that contains a bunch of commands. The main idea of ​​the script is to automatically execute and re-execute a series of commands, instead of manually entering them one by one. For a script, all you need to do is create a simple text file and enter a list of commands to perform a specific task, then save the file. Now when you need to complete this specific task, just run the script file and the job will be done automatically.

This is a basic understanding of what a bash script is. Now let’s talk about script debugging. When we write a small script with several commands, debugging them is just looking at the output and checking that they work as expected. However, for larger scenarios like scripts written for web pages, system configuration, etc., looking only at the output

not enough to find problems. This is where we need a debugging tool. When working with programming languages, there is a debugging tool integrated with them. However, in bash scripts, we don’t have such a tool, but we can use the command line to do debugging.

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

Following are some of the available debugging options on the command line:

  • option -x – displays traces of commands before they are executed
  • option -n – does not display the command, just checks for syntax errors
  • option -v – displays commands as they are read

We are using Debian 10 OS to explain the procedure discussed in this article.

Track progress (-x option)

It tells the shell to display what each command looks like before being executed. It also gives you the choice of whether to debug the entire script or only part of it.

Debugging the entire script

Launching the shell with the –x option will run the entire script in debug mode. In this mode, traces of commands and their arguments are displayed in 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="Привет мир!"
# печать
echo "$var"
# альтернативный способ печати
printf "%sn" "$var"
echo "Мой дом - это: $HOME"

To run the entire script in debug mode, add the -x parameter before the startup script as follows:

$ bash -x ./script_name.sh

In our example, this will be:

$ bash -x ./myscript.sh

Below, our “myscript.sh” is running in debug mode. Added comments are not printed in debugged output.

Debugging part of the script

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

Place the set -x option at the starting point of the area you want to debug, and place the set + x option where you want it to stop. For example, in the following script, we want to debug the scope starting at $ var because we think it is not working as expected. So we’ll wrap it up by putting the set -x option in front of the $ var line, and finish by putting the set + x option on the second last line.

Edit the script file using any editor. For this we use the nano editor:

$ sudo nano myscript.sh

Now enclose the area you want to debug using the set –x and set + x options as described above.

#!/bin/bash
exec 5> debug_output.txt
BASH_XTRACEFD="5"
PS4='$LINENO: '
set -x
var="Привет мир"
# печать
echo "$var"
# альтернативный способ печати
printf "%sn" "$var"
set +x
echo "Мой дом - это: $HOME"

After that use Ctrl + O to save and then Ctrl + X to exit the file.

Then run the command below to execute the script:

$ ./myscript.sh

Disable shell (-n option)

The -n option (short for noexec or no execution) enables syntax checking mode. It tells the shell not to execute commands, but to just check for syntax errors. This is a safe way to debug as it does not execute commands if they contain any error.

Use the following syntax to run this mode:

$ sh –n ./script_name

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

#!/bin/bash
var="Привет мир"
echo "$var"
echo "Мой домашний каталог is=$HOME
echo "Мое имя is=$USER"

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

To debug a script with the –n parameter, use the following command:

$ sh -n ./myscript1.sh

Only syntax errors were not displayed.

Display script commands (-v option)

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

Use the following syntax to run this mode:

$ sh –v ./script_name

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

#!/bin/bash
var="Привет мир"
echo "$var"
echo "Мой домашний каталог is=$HOME”
echo "Мое имя is=$USER"

This is what our script is when we execute it without any debug option.

Now, when we run it with the –v option, it displays the commands until their results.

That’s all for now! We have seen how to debug a bash script using three different command line options. Among these options, the –x parameter allows you to choose whether to debug part of a script or an entire script.

Sidebar