Bash Error Handling and Debugging

Debugging is the process of identifying and resolving errors in computer programs, while error handling involves managing unexpected situations during program execution.  Developers use various techniques in their bash scripts such as setting the -e option to exit on error, enabling verbose mode with set -x, implementing custom error-handling functions with trap, using assertions to check conditions, and employing echo and printf commands as debugging tools.  This article will discuss a comprehensive overview of error handling and debugging in bash script.

What Types of Errors Occur in Bash Scripting?

Before learning the probable solution of error handling and debugging, first understand the type of errors you might face while doing work with bash scripting. Bash scripts can encounter various types of errors, including syntax errors, runtime errors, and logical errors. Examples illustrating the concept are listed below:

  1. Syntax Error: This type of error occurs when there are mistakes in the script’s structure or grammar. For example:
    #!/bin/bash
    
    echo "Hello, World!

    Here, The missing quotation mark after “Hello, World!” leads to a syntax error.

  2. Runtime Error: It stems from issues like undefined variables or incorrect command usage. For instance:
    #!/bin/bash
    
    variable="Hello"
    echo $varible

    The misspelled variable name (“varible” instead of “variable”) causes a runtime error.

  3. Logical Error: It results from flawed script logic, leading to unexpected outcomes. Example:
    #!/bin/bash
    
    num=5
    
    if [ $num -gt 10 ]; then
      echo "The number is greater than 10."
    else
      echo "The number is not greater than 10."
    fi
    

    The script incorrectly states that the number is not greater than 10 due to flawed logic in the if statement.

Now, Handling errors is crucial because it enables your script to gracefully manage unexpected situations and offer valuable feedback. Without it, a script might abruptly halt when encountering an error.

Debugging on the other hand is crucial because it helps identify and rectify errors or bugs in software code. When writing complex programs or scripts, errors are almost inevitable. Debugging allows developers to trace and understand the flow of their code, locate issues, and correct them.

3 Different Debugging Techniques in Bash Script

Debugging is a useful technique for identifying the error in an easy manner. In bash, there are several debugging techniques:

1. Using the “echo” Command to Check the Output

In Bash scripting, printing debug information is crucial for understanding script behaviour. One effective approach is using the echo command strategically to output variable values, messages, or checkpoints. Here is a sample code to have the idea of using it:

#!/bin/bash

#Assigning variable value
name="John"
age=25

#Check if the value is properly assigned or not
echo "Name: $name"
echo "Age: $age"
EXPLANATION

In this Bash script, two variables, name and age, are assigned values “John” and 25, respectively. The echo statements are then used to display the assigned values of these variables. The script essentially verifies the proper assignment of values to the variables and prints the output, showing the assigned name and age. The script then uses the echo command to print the values of the variables.

 the “echo” Command displays the OutputAs the image shows, the echo command ensures that the variables are properly stored in their corresponding variables.

2. Using “set -x” Command to Enable Debug Mode

Bash has a debug mode that prints each command of your script and its arguments as it runs. You can enable it by including set -x at the start of your script or by running it with the -x option.

To understand how the debug mode works with the set -x command, follow the script given below:

#!/bin/bash

set -x
# Specify the value for algebraic sum (e.g., 5)
n=3

# Initialize sum
sum=0

# Calculate algebraic sum using a loop
for ((i = 1; i <= n; i++)); do
  sum=$((sum + i))
done

# Print the result
echo "The algebraic sum of numbers from 1 to $n is: $sum"
EXPLANATION

This Bash script calculates the algebraic sum of numbers from 1 to a specified value ‘n’. It employs the ‘set -x’ option for debugging.  The set -x command shows each step of the script’s execution, aiding in understanding the flow and identifying potential issues.

The script initializes ‘sum’ to zero, then uses a loop to iterate from 1 to ‘n’, updating ‘sum’ in each iteration. Finally, it prints the calculated algebraic sum.

The image displays that the “set -x” Command is enabling the debug mode to inspect the code lineAs you can see from the image given above, the set -x shows each command line written in the script to the terminal window. This provides a useful way to look into each step of execution and detect any potential error if it exists there.

Note: If you use the command export PS4='$0.$LINENO+ ' right after the shebang line in your script, it will enable the debug mode to display the corresponding number of each line. This way, you can easily trace any error line number that may occur in your script.

3. Using the -V Option to Enable the Verbose Mode

When the -v option is utilized in a Bash script, it enables verbose mode, displaying the script’s commands and their arguments before execution. However, if there is any syntax error occurs, the script halts the execution of subsequent lines onwards.

To debug the bash script with -v option, use the set -v command at the beginning of your script:

#!/bin/bash

set -v
# Specify the value for algebraic sum (e.g., 5)
n=3

# Initialize sum
sum=0

# Calculate algebraic sum using a loop
for ((i = 1; i <= n; i++)): do
  sum=$((sum + i))
done

# Print the result
echo "The algebraic sum of numbers from 1 to $n is: $sum"
EXPLANATION

The objective of this Bash script is to calculate the algebraic sum of numbers from 1 to a specified value ‘n’ using a loop. The script begins by setting the verbose mode with ‘set -v’ to display each command before execution. However, there is a syntax error in for ((i = 1; i <= n; i++)): do line where, : is used instead of ; which will cause a syntax error upon execution. Here, using the set -v command will stop code execution on error.

Using the -V Option to Enable the Verbose Mode, a way of error handling and debuggingAs you can see, the code stops executing due to the syntax error. Incorporating set -v command at the beginning of the code helps to avoid the execution of further code lines, once the error is found.

4 Best Practices for Error Handling in Bash Script

For handling errors in your bash script, you can use different methods with the customised error message in your script. Here are four types of error handling techniques discussed below:

1. Employing “trap” Command to Trape the Errors

You can use the trap command with the built-in ERR option to handle the error if any such situation occurs.

To use the trap command, first, you should create a customised error-handling function at the beginning of the script. Then call the custom function with the help of the trap command to handle the error gracefully:

#!/bin/bash

handle_error() {
    echo "An error occurred. Exiting..."
    exit 1
}

trap handle_error ERR

# Your script code here
# Example: Division by zero to trigger an error
read -e "Enter a number:" num

result=$((10 / num))

echo "Result: $result"
EXPLANATION

In this code, the handle_error function is defined to display an error message and exit the script with a status of 1. Here, the script causes a potential error by using -e instead of -p in read -e "Enter a number:" num line. The trap handle_error ERR line establishes a trap, initiates the handle_error function to be executed when any command in the script encounters an error (non-zero exit status).

Employing “trap” Command to Trape the Errors, another way of error handing and debuggingAs you can see, the given code causes an error because of the misgiven option. The customize handle_error function gives an error warning and does not proceed further in the code.

2. Using Exit Codes to Handle the Error

The potential error can be handled with an exit code. After executing a command, you can access the command’s exit code using $? Syntax and employ if-else statement to print the outcome.

To use an exit code in error handling, you can use the following code as a sample:

#!/bin/bash

# Example command that may fail
ls non_existent_directory

# Check the exit code of the last command
if [ $? -eq 0 ]; then
    echo "Command executed successfully."
else
    echo "Command failed with exit code $?."
fi
EXPLANATION

The given Bash script attempts to list the contents of a non-existent directory using the ls command. After the command execution, it checks the exit code of the last command using the $? variable. If the exit code is 0 (indicating success), it prints “Command executed successfully.” Otherwise, it prints “Command failed with exit code $?” to signify an unsuccessful execution, providing information about the encountered error.

Using Exit Codes to Handle and exit from the errorSince there is no non_existent_directory in the current directory, the code occurs error, and print Command failed with exit code 1 in the current directory.

3. Using the set -e and set -u options

The set -e option in Bash instructs the shell to exit immediately if any command it executes exits with a non-zero status, indicating an error. On the other hand, set -u treats unset variables as errors and causes the shell to exit if any variable is referenced before being assigned a value.

To handle any potential error in the bash script, you can use set -e and set -u at the beginning of your script:

#!/bin/bash

set -e
set -u
# Specify the value for algebraic sum (e.g., 5)
n=3

# Initialize sum
sum=0

# Calculate algebraic sum using a loop
for ((i = 1; i <= n; i++)): do
  sum=$((sum + i))
done

# Print the result
echo "The algebraic sum of numbers from 1 to $n is: $sum"
EXPLANATION

The given code intends to initialize the variable n to 3 and sum to 0. Then, it calculates the algebraic sum from 1 to n using a loop and prints the result. The loop iterates from 1 to n, updating the sum variable by adding the current loop index. Finally, the script echoes the calculated algebraic sum. However, this line for ((i = 1; i <= n; i++)): do contain a syntax error where : has been used instead of ;, thus will create a syntax error upon execution.

Using the set -e and set -u optionsFrom the image shown above, the bash file does not proceed further once it is encountered by the syntax error in for ((i = 1; i <= n; i++)): do line. The set -e command ensures to stop the file running further.

4. Handle Error Through The If-Else Statement

To handle errors using an if-else statement in Bash, you can use the different options to check the exit status of the condition. For instance, if you want to check if a file exists or not.

To check whether a file exists or not and handle errors while proceeding with the code, you can use the following script with an if else statement:

#!/bin/bash

# Check if a file exists
if [ ! -e "file.txt" ]; then
echo "Error: File does not exist"
else
echo "File does exist."
fi
EXPLANATION

The Bash script checks for the existence of a file named “file.txt” in the current directory. Utilizing the conditional statement if [ ! -e "file.txt" ]; then, it verifies if the file is not present. If the file does not exist, it outputs an error message with “Error: File does not exist.” Otherwise, in the else block, it prints “File does exist.”

Handle Error Through The If-Else StatementSince the file named file.txt does not exist in the current directory, the bash code returns “Error: File does not exist” to the command line.

Conclusion

Error handling and debugging are crucial aspects of programming to ensure that any code serves its purpose effectively. Properly finding errors and understanding their root cause makes a programmer more effective and efficient. I hope this article has provided you with a fundamental understanding of these matters. If you have any questions or opinions you would like to share with us related to this article, please leave a comment below. Happy coding!

People Also Ask

How do you handle errors in Bash?

Regarding error handling and debugging, errors are commonly handled using conditional statements in bash, such as if and else, and checking the exit status of commands using the $? variable. Additionally, the trap command can be employed for signal handling and error recovery. The specific approach depends on the context and requirements of the script.

How do I debug a Bash command?

To debug a bash command, you can follow the steps given below:

  1. Print Statements: Insert echo statements at key points in your script to print variable values, command outputs, or any information that helps you understand the script’s flow.
    # Example with echo statements for debugging
    
    echo "Starting script..."
    variable="some_value"
    echo "Variable value: $variable"
  2. x option: Use the “-x” option to enable debugging for the entire script. Place set -x at the beginning of your script:
    #!/bin/bash
    
    set -x
    # rest of your script

    This prints each command and its arguments to the standard error output as they are executed.

  3. trap command: Use the “trap” command to set up a trap for errors (ERR) or signals, allowing you to execute specific commands for debugging or error handling:
    # Example using trap for error handling
    trap 'echo "Error occurred in line $LINENO"; exit 1' ERR
  4. Use external tools like Shellcheck to analyze your script for common issues and provide suggestions for improvement:
    shellcheck your_script.sh
  5. Use an interactive debugger like bashdb for more advanced debugging. Install it and use it to step through your script:
    bashdb your_script.sh

    Choose the method that suits your debugging needs and helps you identify and resolve issues in your Bash scripts effectively.

How does a bash script work?

When executing a bash file, the script is interpreted by the Bash shell, which reads and executes each command sequentially. The script starts running from the top, and each line is processed in order. Commands can include system commands, control structures like loops and conditionals, variable assignments, and function calls. The script inherits the environment of the shell that runs it, and it can include comments for documentation.

How do I run a bash script verbose?

To run a Bash script in verbose mode, you can use the -x option. This can be done by modifying the shebang line (the first line of the script) or by running the script with the Bash interpreter explicitly along with the -x option.

Run the bash script in verbose mode by modifying the shebang line in your bash script, like the following:

#!/bin/bash -x

Alternatively, you can run the script in verbose mode using the following command:

bash -x myscript.sh

Here myscript.sh is the bash file for which you want to enable the verbose mode.

The -x option enables the script to print each command and its arguments to the standard error output before executing them. This helps you track the execution flow and debug any issues by providing a detailed trace of the script’s activity.

Related Articles


<< Go Back to Bash Scripting Tutorial

Rate this post
LINUX
FUNDAMENTALS
A Complete Guide for Beginners Enroll Course Now
Mohammad Shah Miran

Hey, I'm Mohammad Shah Miran, previously worked as a VBA and Excel Content Developer at SOFTEKO, and for now working as a Linux Content Developer Executive in LinuxSimply Project. I completed my graduation from Bangladesh University of Engineering and Technology (BUET). As a part of my job, i communicate with Linux operating system, without letting the GUI to intervene and try to pass it to our audience.

Leave a Comment