How to use try catch command in bash

How to Use TRY CATCH Command in Bash

In this guide, we’ll cover how to use try catch command in Bash to handle possible errors in the bash script. Continue reading this article to find out more. 

Try Catch Command in BASH

Error handling in the bash script is difficult. The bash script has no specific try catch command, construct, or block to handle the exceptions and errors. Unlike other high-level languages, bash does not have a debugger to log the errors. 

However, there are other techniques to use different bash commands to handle errors. These error handling techniques aren’t mature like try catch constructs, but help catch potential bash errors. 

One more thing to remember is that the “try/catch” is a programming term used to handle errors in the code. Though most high-level languages have the support for try/catch keywords, you can still program logic to catch errors and exceptions. 

Therefore, in this guide, we’ll explore approaches you can use as a substitute in bash. Continue reading this guide to find out how to use try catch command in bash.

How to Use TRY CATCH Command in Bash

In this section, you’ll learn how to use try catch command in bash to handle basic errors. We’ll discuss six methods in detail. So, let’s get started.

Check the Exit Status

The first method is to check the exit status of the bash script. The syntax for the exit status looks like this:

if ! some_command; then
    echo "some_command returned an error"
fi

There’s a built-in variable called $? that tells the exit status of the last executed bash command. For instance, if you want to check the exit status of the bash script, you’ll use $? in combination with the if/else block. 

For this step, first, open the terminal by pressing “Ctrl + Alt + T”. Next, create a file using the nano or vim editor:

nano script.sh
vim script.sh

Add the following code in the bash script file:

# run some command
status=$?
if [ $status -eq 1 ]; then
    echo "General error"
elif [ $status -eq 2 ]; then
    echo "Misuse of shell builtins"
elif [ $status -eq 126 ]; then
    echo "Command invoked cannot execute"
elif [ $status -eq 128 ]; then
    echo "Invalid argument"
fi

   Now, you can replace the #run some command comment with any correct or wrong command to view the different error logs.

Use OR and AND Operator

Another method you can opt for is the usage of AND and OR operator in bash scripts. To elaborate, use the || and && between two commands from the terminal or inside the bash script. Here is the syntax:

command1 || command2
command1 && command2

The || operator executes command 2 if command 1 fails. On the other hand, the && operator runs command 2 if and only if command 1 executes successfully. 

For example, if you want to print something on the terminal only if the update has been completed successfully, then write:

sudo apt update && echo “Success”

The output looks like this:

use try catch command in bash

Exit on Errors in Bash

The next method to use the try catch command in bash is to exit the script on an error encounter. By default, the bash script continues to execute even if it throws an error. The error is sent to stderr, but the script execution does not stop.  

However, this default behavior does not allow error-handling mechanisms. To execute the exit on the error mechanism in bash, use the set command. For example, to add the exit on error code inside a bash script, the syntax looks like this:

set -e
#
# Some critical code blocks where no error is allowed
#
set +e

In this case, the set command causes bash to exit the execution immediately if any of the previous commands exit with a non-zero status. The non-zero status is only caused when there is an error. Otherwise, the status is always set to 0. 

For instance, to test the wrong command, type:

set -e
#
eho “This is a test code”
#
set +e

In addition, you can also use the set command with the pipeline. The default pipeline behavior only returns a non-zero exit status if the last command in the pipeline fails. So any error that occurs between the different commands in the pipe is not reflected outside the pipe. 

For example:

set -e
true | false | true   
echo "This is a test code" 

You’ll get this output:

set command in bash

The above script didn’t detect false between the pipe and continued the execution of the pipeline. However, if you want the pipeline to exit on failure, use the pipefail option with the set command. Specifically, type:

set -o pipefail -e
true | false | true       
echo "This will not be printed"

Now, the output will look like this:

pipefail in bash

Here’s the complete syntax for the exit on an error in the pipeline:

set -o pipefail -e
#
# Some critical code blocks where no error or pipeline error is allowed
#
set +o pipefail +e

In addition, here is the example that will successfully execute the installation process inside the bash script:

#!/bin/bash
set -e
sudo apt install firefox
echo "Command succeeded"

In case, there is some error, it will exit on that error.

Try Catch Functions in Bash

Since a bash script has no try/catch command, you can create your complex try catch functions to handle different exceptions and errors. This way, you’ll be able to use try catch command in bash. This’ll give you more control over the error-handling mechanism, and you can mimic the try catch behavior more flexibly. 

For example, type this code in the script file:

function try()
{
    [[ $- = *e* ]]; SAVED_OPT_E=$?
    set +e
}
function throw()
{
    exit $1
}
function catch()
{
    export exception_code=$?
    (( $SAVED_OPT_E )) && set +e
    return $exception_code
}

In this script, we’ve created three functions for try, catch, and exception.

The try part of the code consists of the actual code. The throw function raises the exception. In addition, we don’t want the bash to exit on the error, so we’ve used the set command inside the catch function. 

To demonstrate the above concept in detail, here’s another code that you can use as a try/catch mechanism in bash:

# Define custom exception types
export ERR_BAD=100
export ERR_WORSE=101
export ERR_CRITICAL=102
try
(
    echo "Start of the try block"
    # When a command returns a non-zero, a custom exception is raised.
    run-command || throw $ERR_BAD
    run-command2 || throw $ERR_WORSE
    run-command3 || throw $ERR_CRITICAL
    # This statement is not reached if there is any exception raised
    # inside the try block.
    echo "End of the try block"
)
catch || {
    case $exception_code in
        $ERR_BAD)
            echo "This error is bad"
        ;;
        $ERR_WORSE)
            echo "This error is worse"
        ;;
        $ERR_CRITICAL)
            echo "This error is critical"
        ;;
        *)
            echo "Unknown error: $exit_code"
            throw $exit_code # re-throw an unhandled exception
        ;;
    esac
}

The previous code covered only one exception, but this one handles custom exceptions depending on the error condition. Here’s the output of the above script:

Try Catch Command in Bash Using the -x Option

The -x flag is one of the options used with the bash command. It is commonly used to debug the bash execution. In addition, the execution shows the interpretation of each line of code on the console. 

To use this option with the bash command for debugging, type:

bash -x script.sh

The output looks like this:

use the -x option

Use Subroutine to Use Try Catch Command in Bash

Alternatively, you can also create subroutines with the set command to use try catch command in bash script. The syntax is:

(
  set -e
  echo "Do one thing"
  echo "Do another thing"
  some_command
  echo "Do yet another thing"
  echo "And do a last thing"
)

Here’s the output of the above command in which we replaced some_command with this code:

touch newScript.sh

Output:

use try catch command in bash

This subroutine will exit if the exit code is greater than 0. Here is a more comprehensive code on using subroutines that simulates the try/catch command:

#!/bin/bash
function a() {
  # do some stuff here
}
function b() {
  # do more stuff here
}
# subshell of try
# try
(
  # This flag will make to exit from the current subshell on any error
  # inside it (all functions run inside will also break on any error)
  set -e
  a
  b
  # do more stuff here
)
# subshell of catch
# catch
errorCode=$?
if [ $errorCode -ne 0 ]; then
  echo "We have an error"
  # We exit the all script with the same error, if you don't want to
  exit $errorCode
fi

Conclusion

In this article, we have covered the alternate statements, commands, and options that you can use to learn how to use try catch command in bash. Since the bash script does not support try/catch, using the subroutines, -x flag, set command, and exit status are some of the methods to apply the try/catch functionality. 

Interested in becoming an expert in bash? Check out how to pass named arguments in bash, learn if/else and use awk command.

If this article helped you, please share it

Related Posts