In the very old days of computer technology, the initial problems with computers were due to real insects. Due to this, fault finding was later called as finding a bug. Therefore, the process of finding and fixing the problems in computers was called debugging.
The process of debugging involves the following:
In the actual debugging process, you will need to do the following:
debug_sp: line 11: [7: command not found]
file: line 6: unexpected EOF while looking for matching `"'
These messages inform the user about the line numbers of script which contain errors.
In the Bash shell, the -n
option is a shortcut for noexec (as in no execution). This option tells the shell to not run the commands. Instead, the shell just checks for syntax errors.
We can test the script as follows:
$ bash –n hello.sh
The –n option will tell the Bash shell to check the syntax in the Shell script; but not to execute the Shell script.
Another way to do this is as follows:
#!/bin/bash -n We have modified shebang line.
In this case, we can test the Shell script as follows:
$ chmod u+x hello.sh $ ./hello.sh
This option is safe, since the shell commands are not executed. We can catch incomplete if, for, while, case, and similar programming constructs as well as many more syntactical errors.
Let's write debug_01.sh
:
#!/bin/bash echo -n "Commands in bin directory are : $var" for var in $(ls ) do echo -n -e "$var " do # no error if "done" is typed instead of "do"
Save the file, give the permission to execute, and run the script as follows:
$ chmod u+x debug_01.sh $ ./debug_01.sh
Output:
Commands in bin directory are : ./hello.sh: line 7: syntax error near unexpected token `do' ./hello.sh: line 7: `do' $ bash –n debug_01.sh
Output:
hello.sh: line 7: syntax error near unexpected token `do' hello.sh: line 7: `do'
The -v
option tells the shell to run in a
verbose mode. In practice, this means that the shell will echo each command prior to executing the command. This will be useful in locating the line of script that has created an error.
We can enable the script execution with the –v
option as follows:
$ bash –v hello.sh
Another way is by modifying the shebang line as follows:
#!/bin/bash -v
In this case, we can run the script with the –v
option as follows:
$ chmod u+x hello.sh $ ./hello.sh
Let's write the script debug_02.sh
, shown as follows:
#!/bin/bash echo "Hello $LOGNAME" echo "Today is `date` echo "Your present working directory is $PWD echo Good-bye $LOGNAME
Save the file, give the permission to execute, and run the script as follows:
$ chmod u+x debug_02.sh $ ./debug_02.sh
Output:
Hello student Today is Fri May 1 00:18:52 IST 2015 Your present working directory is /home/student/work Good-bye student
Let's enable the –v
option for debugging, and run the script again as follows:
$ bash –v debug_02.sh
Output:
#!/bin/bash echo "Hello $LOGNAME" "Hello student" echo "Today is `date` date "Today is Fri May 1 00:18:52 IST 2015 echo "Your present working directory is $PWD "Your present working directory is /home/student/work echo Good-bye $LOGNAME Good-bye student
The -x
option, short for xtrace or execution trace, tells the shell to echo each command after performing the substitution steps. Thus, we will see the value of variables and commands.
We can trace the execution of the Shell script as follows:
$ bash –x hello.sh
Instead of the previous way, we can modify the shebang line as follows:
#!/bin/bash -x
Let's test the earlier script debug_01.sh
as follows:
$ bash –x hello.sh
Output:
$ bash –x debug_02.sh + echo Hello student Hello student + date + echo The date is Fri May 1 00:18:52 IST 2015 The date is Fri May 1 00:18:52 IST 2015 + echo Your home shell is /bin/bash Your home shell is /bin/bash + echo Good-bye student Good-bye student
Let's try the following programs with the –n
–v
–f
and –x
options. Here's a sample program—debug_03.sh
:
#!/bin/bash echo "Total number of parameters are = $#" echo "Script name = $0" echo "First Parameter is $1" echo "Second Parameter is $2" echo "All parameters are = $*" echo "File names starting with f* in current folder are :" ls f*
Save the file, give the permission to execute, and run the script as follows:
$ chmod u+x debug_03.sh $ ./debug_03.sh One Two
Output:
"Total number of parameters are = 2" "Script name = ./debug_03.sh" "First Parameter is India" "Second Parameter is Delhi" "All parameters are = India Delhi" "File names starting with debug_02.sh debug_03.sh in current folder are: " debug_02.sh debug_03.sh
Let's test the same script with the –n
option, which will check for syntax errors:
$ bash –n debug_03.sh One Two
Let's test the same script with the –v
option:
$ bash –v debug_03.sh One Two
Output:
#!/bin/bash echo "Total number of parameters are = $#" "Total number of parameters are = 2" echo "Script name = $0" "Script name = debug_03.sh" echo "First Parameter is $1" "First Parameter is India" echo "Second Parameter is $2" "Second Parameter is Delhi" echo "All parameters are = $*" "All parameters are = India Delhi" echo "File names starting with d* in current folder are :" "File names starting with debug_02.sh debug_03.sh in current folder are: " ls d* debug_02.sh debug_03.sh
Let us test the same script with the –x
option:
$ bash –x debug_03.sh One Two
Output:
+ echo $'342200234Total' number of parameters are = $'2342200235' "Total number of parameters are = 2" + echo $'342200234Script' name = $'debug_03.sh342200235' "Script name = debug_03.sh" + echo $'342200234First' Parameter is $'India342200235' "First Parameter is India" + echo $'342200234Second' Parameter is $'Delhi342200235' "Second Parameter is Delhi" + echo $'342200234All' parameters are = India $'Delhi342200235' "All parameters are = India Delhi" + echo $'342200234File' names starting with debug_02.sh debug_03.sh in current folder are $':342200234' "File names starting with debug_02.sh debug_03.sh in current folder are: " + ls debug_02.sh debug_03.sh debug_02.sh debug_03.sh
Let's test one more program, which will give a syntax error during the –n
and –x
options debugging. Write the Shell script debug_04.sh
as follows:
#!/bin/bash echo "Commands in bin directory are : $var" for var in $(ls ) do echo -n -e "$var " do
Save the file, give the permission to execute, and run the script as follows:
$ chmod u+x debug_04.sh $ bash –n debug_04.sh
Output:
debug_04.sh: line 7: syntax error near unexpected token `do' debug_04.sh: line 7: `do'
The preceding program has a syntax error on line number 7. The word do
has an error. We need to change word "do" to "done".
The following is a summary of various debugging options used for debugging, such as -x
, -v
, and -n
with their details:
$ bash –n script_name // interpretation without execution $ bash –v script_name // Display commands in script $ bash –x script_name // Trace the execution of script $ bash –xv script_name // Enable options x and v for debugging $ bash +xv script_name //Disable options x and v for debugging
Most of the time, we invoke the debugging mode from the first line of script. This debugging mode will remain active until the last line of code. But many times, we may need to enable debugging for a particular section of script. By using the set command, we can enable and disable debugging at any point in our Shell script:
set -x section of script set +x
Consider the following script:
#!/bin/bash str1="USA" str2="Canada"; [ $str1 = $str2 ] echo $? Set –x [ $str1 != $str2 ] echo $? [ -z $str1 ] echo $? Set +x [ -n $str2 ] echo $? Exit 0
In this case, the debugging will be enabled after the set -x
and will be disabled immediately after the set +x
.
The following table summarises the various options for the set
command:
For general debugging, we can use the vi editor along with certain options.
During debugging, many times we search for a pattern throughout the complete document. It is preferable to highlight the searched item. We will enable search pattern highlighting by using the following command in the vi editor when the document is opened:
:set hlsearch :set ic vi –b filename
We can even modify the vi editor configuration file—.exrc
or .vimrc
so that we need not give the previous command again and again.
If we follow certain good practices, then we will face errors. Even if errors are found, these will be easier to debug:
if [ $rate -lt 3 ] then echo "Sales tax rate is too small." fi
WORKING_DIR=$HOME/work if [ -e $WORKING_DIR] then # Do something.... fi