Error Handling In Shell Programming
Contents |
and Signals and Traps (Oh My!) - Part 1 by William Shotts, Jr. In this lesson, we're going to look at handling errors during the execution of your scripts. The difference between a good program and a poor one is often measured in terms of the shell script exit code program's robustness. That is, the program's ability to handle situations in which something goes wrong. shell script exit on error Exit status As you recall from previous lessons, every well-written program returns an exit status when it finishes. If a program finishes successfully, the bash script trap exit status will be zero. If the exit status is anything other than zero, then the program failed in some way. It is very important to check the exit status of programs you call in your scripts. It
Bash Script Exit On Error
is also important that your scripts return a meaningful exit status when they finish. I once had a Unix system administrator who wrote a script for a production system containing the following 2 lines of code: # Example of a really bad idea cd $some_directory rm * Why is this such a bad way of doing it? It's not, if nothing goes wrong. The two lines change the working directory to the name contained in $some_directory and delete bash if exit code the files in that directory. That's the intended behavior. But what happens if the directory named in $some_directory doesn't exist? In that case, the cd command will fail and the script executes the rm command on the current working directory. Not the intended behavior! By the way, my hapless system administrator's script suffered this very failure and it destroyed a large portion of an important production system. Don't let this happen to you! The problem with the script was that it did not check the exit status of the cd command before proceeding with the rm command. Checking the exit status There are several ways you can get and respond to the exit status of a program. First, you can examine the contents of the $? environment variable. $? will contain the exit status of the last command executed. You can see this work with the following: [me] $ true; echo $? 0 [me] $ false; echo $? 1 The true and false commands are programs that do nothing except return an exit status of zero and one, respectively. Using them, we can see how the $? environment variable contains the exit status of the previous program. So to check the exit status, we could write the script this way: # Check the exit status cd $some_directory if [ "$?" = "0" ]; then rm * else echo "Cannot change directory!" 1
and Signals and Traps (Oh, My!) - Part 2 by William Shotts, Jr. Errors are not the only way that a script can terminate unexpectedly. You also have to be concerned with signals. Consider the following program: #!/bin/bash echo "this script will endlessly loop until you stop it" while true; do : # trap command in shell script Do nothing done After you launch this script it will appear to hang. Actually, like most programs
Exit Bash Shell
that appear to hang, it is really stuck inside a loop. In this case, it is waiting for the true command to return a non-zero
Linux Kernel Error Codes
exit status, which it never does. Once started, the script will continue until bash receives a signal that will stop it. You can send such a signal by typing ctrl-c which is the signal called SIGINT (short for SIGnal INTerrupt). Cleaning up after http://linuxcommand.org/wss0150.php yourself OK, so a signal can come along and make your script terminate. Why does it matter? Well, in many cases it doesn't matter and you can ignore signals, but in some cases it will matter. Let's take a look at another script: #!/bin/bash # Program to print a text file with headers and footers TEMP_FILE=/tmp/printfile.txt pr $1 > $TEMP_FILE echo -n "Print file? [y/n]: " read if [ "$REPLY" = "y" ]; then lpr $TEMP_FILE fi This script processes a text file specified on http://linuxcommand.org/wss0160.php the command line with the pr command and stores the result in a temporary file. Next, it asks the user if they want to print the file. If the user types "y", then the temporary file is passed to the lpr program for printing (you may substitute less for lpr if you don't actually have a printer attached to your system.) Now, I admit this script has a lot of design problems. While it needs a file name passed on the command line, it doesn't check that it got one, and it doesn't check that the file actually exists. But the problem I want to focus on here is the fact that when the script terminates, it leaves behind the temporary file. Good practice would dictate that we delete the temporary file $TEMP_FILE when the script terminates. This is easily accomplished by adding the following to the end of the script: rm $TEMP_FILE This would seem to solve the problem, but what happens if the user types ctrl-c when the "Print file? [y/n]:" prompt appears? The script will terminate at the read command and the rm command is never executed. Clearly, we need a way to respond to signals such as SIGINT when the ctrl-c key is typed. Fortunately, bash provides a method to perform commands if and when signals are received. trap The trap command allows you to execute a command when a signal is received by your script. It works like this: trap arg signals "signals" is a list of sign
here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta http://stackoverflow.com/questions/64786/error-handling-in-bash Discuss the workings and policies of this site About Us Learn more about Stack Overflow the company Business Learn more about hiring developers or posting ads with us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack Overflow Community Stack Overflow is a community of 4.7 million programmers, just like shell script you, helping each other. Join them; it only takes a minute: Sign up Error handling in BASH up vote 143 down vote favorite 109 What is your favorite method to handle errors in BASH? The best example of handling errors in BASH I have found on the web was written by William Shotts, Jr at http://www.linuxcommand.org. William shell script exit Shotts, Jr suggests using the following function for error handling in BASH: #!/bin/bash # A slicker error handling routine # I put a variable in my scripts named PROGNAME which # holds the name of the program being run. You can get this # value from the first item on the command line ($0). # Reference: This was copied from