Error Handling with Exit Codes and Signals

Tutorial 2 of 5

Error Handling with Exit Codes and Signals

1. Introduction

Goal

In this tutorial, we aim to provide you with a thorough understanding of how to handle exit statuses and error codes in shell scripts.

Learning Objectives

Upon completion of this tutorial, the user would be able to:
- Understand the concept of exit codes and signals in shell scripts.
- Interpret different exit codes appropriately.
- Implement error handling in shell scripts.

Prerequisites

  • Basic knowledge of shell scripting.
  • Familiarity with Unix/Linux command line.

2. Step-by-Step Guide

Exit codes, also known as return statuses, are a way for a program to report to its caller about whether it succeeded or failed. By convention, an exit code of 0 indicates success, and any non-zero exit code indicates failure.

Signals are a limited form of inter-process communication in Unix and Unix-like systems. They're used to notify a process of important events.

Error handling in Shell Script

In shell scripts, you can use the special variable $? to get the exit status of the last executed command. Here's an example:

# Run a command
ls /non/existent/directory

# Check the exit status
echo $?

3. Code Examples

Example 1: Simple Error Handling

#!/bin/bash

# Run a command
ls /non/existent/directory

# Check the exit status
if [ $? -eq 0 ]; then
  echo "The command was successful."
else
  echo "The command failed."
fi

In this script, we first run a command that's expected to fail (ls /non/existent/directory). Then, we check the exit status of the last executed command. If it's 0, we print a success message. Otherwise, we print a failure message.

Example 2: Handling Signals

#!/bin/bash

# Define a signal handler
handle_sigint() {
  echo "Caught SIGINT, exiting."
  exit 1
}

# Install the signal handler
trap handle_sigint SIGINT

# Wait indefinitely
while true; do
  sleep 1
done

In this script, we define a function handle_sigint to handle SIGINT signals. Inside the function, we print a message and exit with a non-zero status. Then, we install the signal handler using the trap command. Finally, we start an infinite loop that waits indefinitely.

4. Summary

In this tutorial, we have covered:
- The concepts of exit codes and signals in shell scripts.
- How to interpret different exit codes.
- How to handle errors in shell scripts.

The next step for learning is to explore more about shell scripting. You can refer to the Advanced Bash-Scripting Guide for more information.

5. Practice Exercises

Below are some exercises for you to practice:

  1. Write a shell script that checks the exit status of every command you run.

  2. Write a shell script that catches SIGINT and SIGTERM signals and prints a message before exiting.

Solutions:

#!/bin/bash

for command in "$@"; do
  $command
  if [ $? -eq 0 ]; then
    echo "$command succeeded"
  else
    echo "$command failed"
  fi
done

In this script, we loop over all arguments ("$@"). For each argument, we run it as a command and check its exit status.

#!/bin/bash

handle_signal() {
  echo "Caught signal, exiting."
  exit 1
}

trap handle_signal SIGINT SIGTERM

while true; do
  sleep 1
done

In this script, we define a function handle_signal to handle signals. Inside the function, we print a message and exit with a non-zero status. Then, we install the signal handler using the trap command. Finally, we start an infinite loop that waits indefinitely.