Using Exit Status Codes in Bash Scripts

In Bash scripting, exit status codes are numeric values returned by commands or scripts to indicate the result of execution. By understanding and using these codes, you can make your scripts more reliable and responsive to failures.

Typically, an exit code of 0 indicates success, while any non-zero value signals an error.

In this tutorial, we will go through the syntax of using exit status codes, with well detailed examples, and best practices for how to use them in a bash shell script. This tutorial is part of error handling in bash.

Syntax

The syntax for using exit status codes in Bash scripts is simple. You can check the exit status of a command using the $? variable, or explicitly set an exit code with the exit command.

</>
Copy
# Check the exit status of the previous command
[ $? -eq 0 ]
</>
Copy
# Set a custom exit code
exit 1

The $? variable captures the exit code of the last executed command, and the exit command sets the exit code for the script.

Examples

Let’s explore how to use exit status codes with four detailed examples.

1. Checking Command Success

In this example, we check if a file exists using the ls command and verify the exit status to determine the result.

example.sh

</>
Copy
#!/bin/bash

# Check if file exists
ls /path/to/file.txt

# Check exit status
if [ $? -eq 0 ]
then
    echo "File found."
else
    echo "File not found."
    exit 1
fi

Output

Using Exit Status Codes in Bash Scripts - Checking Command Success

In this script, if the file does not exist, the ls command returns a non-zero exit code, triggering the error message and exiting with code 1.

2. Using Custom Exit Codes

Custom exit codes help differentiate between various types of errors. In this example, we explicitly set exit codes based on different conditions.

example.sh

</>
Copy
#!/bin/bash

# Check if argument is provided
if [ -z "$1" ]
then
    echo "No argument provided."
    exit 2
fi

echo "Argument provided: $1"
exit 0

Output

Using Custom Exit Codes in Bash Scripts

If no argument is provided, the script exits with code 2. You can check the exit code using echo $? to understand the script’s result.

3. Using set -e for Automatic Error Handling

The set -e command makes the script exit immediately if any command returns a non-zero exit code. This is useful for preventing the script from continuing after a failure.

example.sh

</>
Copy
#!/bin/bash

# Enable automatic error handling
set -e

# This command will fail
cp /nonexistent/file /tmp/

# This line will not be executed
echo "This message will not appear."

Output

Exit Status Codes in Bash Scripts - Using set -e for Automatic Error Handling

With set -e enabled, the script exits immediately upon encountering an error, preventing further execution.

example.sh (Updated)

</>
Copy
#!/bin/bash

# Enable automatic error handling and pipefail
set -e set -o pipefail
# This command fails, and the script should exit immediately
cat /nonexistent/file | grep "text"

# This line will not be executed if set -o pipefail is active
echo "This line will not appear."

Output

Using Exit Status Codes in Bash Scripts

Explanation

  • set -e: This option makes the script exit immediately if any command returns a non-zero exit code.
  • set -o pipefail: This ensures that the exit code of a pipeline is the exit status of the first failing command, not the last command.

With both set -e and set -o pipefail enabled, the script exits immediately after the failure of cat, and the line “This line will not appear.” is never executed. This is the expected behavior for handling errors effectively in pipelines.

Best Practices for Using Exit Status Codes

  • Always check the exit status of critical commands using $? to ensure they succeeded.
  • Use custom exit codes to distinguish between different error conditions in your scripts.
  • Enable set -e and set -o pipefail at the beginning of your scripts for better error handling.
  • Log errors with meaningful messages to help identify the issue during troubleshooting.
  • Test your scripts with different inputs and scenarios to verify that exit codes are handled correctly.

By following these best practices, you can write more robust Bash scripts that effectively manage errors and improve reliability.