How to Enable Shell Script Debugging Mode in Linux?
Linux is a very popular operating system especially among developers and in the computer science world, as it comes along with its powerful ability to play with the kernel. Major Linux distributions (often referred to as Linux distros) are Open Source (Source Code available and can be modified on request) in nature like Ubuntu, CentOS, etc.
Bash is a very popular shell scripting language that is executed in the back-end when you open the terminal in Linux. DevOps (Operations Team responsible for deployment more often) use Bash/Shell scripting (series of commands written in a file to execute together in an ordered fashion) to automate usual/minimalist/trivial tasks for example running checking of time stamps on which file is generated/updated, checking for a number of files, etc.
Debugging is terminology that means the process of identifying errors and possibly resolving them in computer hardware or software. Just like all the other programming/coding languages debugging is crucial in bash/shell scripting in order to understand the flow of the program and resolve any errors if they occur.
In this article let us discuss two ways of debugging a shell script, to help strengthen the understanding I will try to take 1 simple shell script (Hello World and List) and will build on it with an example of a conditional shell script (odd/even).
1. Using bash options (-x, -n, -v): The following are various options explained in detail:
- -x: It helps in tracing command output before executing them, when we run the script using this option we get each line of code traced before it is executed and its respective output printed in the terminal. The following is a simple HelloWorld.sh script and its execution screenshots depict the same.
#! /bin/bash # print Hello World echo 'Hello World' # Listing all components on root ls /
In the above figure we see code traced (printed) before it is executed, then its relevant output, and further the code for listing (ls) is traced followed by its execution. Let’s build further with the following example (OddEven.sh) which prompts the user for input and tells whether the entered number is Odd/Even Number.
#! /bin/bash # Take input from the user echo -n "Enter a number" read n # Calculate remainder using mod (%) operator remainder=$(( $n % 2 )) # Odd or Even Check if [ $remainder -eq 0 ] then echo "You have entered $n -- which is an Even number" else echo "You have entered $n -- which is an Odd number" fi
Similar to the prior example each line of code is traced before it is executed.
- -n: It helps in checking the syntax errors if there are any in the shell script prior to executing it. With a boom in the technology of cloud computing, it is essential to know various command-line options to check syntax errors. It is difficult to have GUI (Graphical User Interfaces) or designated IDEs (Integrated Development Environments) on Virtual Machines executing in the cloud. So this option helps with getting syntax checks performed on a script using CLI (Command Line Interface). Let’s understand its application using the example below which has OddEven.sh Script which by purpose has a small syntax error.
#! /bin/bash # Take input from the user echo -n "Enter a number" read n # Calculate remainder using mod (%) operator remainder=$(( $n % 2 )) # Odd or Even Check if [ $remainder -eq 0 ] then echo "You have entered $n -- which is an Even number' else echo "You have entered $n -- which is an Odd number" fi
When the script is executed with -n option output shows the exact line number location of the line of code where it got a syntax error. Then when the error is fixed and run it again with the same option the following output is shown-
This shows that the script is syntax-errors-free.
- -v: If there is a need to read the comments and entire script while the script is executing, then -v option helps us achieve this goal. The following example screenshot shows how -v and -x differ from each other and how we can use -v option. The same OddEven.sh script file as shown in the above examples is used in the below example.
In the above code all comments and code are visible (like the entire “if block” and not only the lines which are executed).
One slight drawback with this is there is a need to perform debug checks on the entire script, if the script is huge it is quite tough/tedious to find useful insights from the output of -x option. So let us have a look at debugging only some specific part of a script in the Next way of Debugging.
2. Using set -x inside script for the specific script.
Let’s assume we want to debug/trace only a certain logical part of OddEven.sh Script and not the whole script. We can set -x flag before the code we want to debug and then set it again back to +x where tracing of code needs to be disabled. The following example code and screenshot help us depict this scenario.
#! /bin/bash # Take input from the user echo -n "Enter a number" read n # Enabling trace set -x # Calculate remainder using mod (%) operator remainder=$(( $n % 2 )) # Disabling trace set +x # Odd or Even Check if [ $remainder -eq 0 ] then echo "You have entered $n -- which is an Even number" else echo "You have entered $n -- which is an Odd number" fi
Here in this example only the logical bit of OddEven.sh Script is being debugged. Only those outputs are traced in terminal output where the set -x option is specified.