Bash Error Handling Set E
Contents |
Creative
Linux Bash Error Handling
Commons licensed. I used to be error handling in bash shell script a fan of “set -e” in shell scripts. It causes bash throw error the script to exit immediately if an error occurs, except where you explicitly handle the error with: some_command_that_might_fail ||
Bash Catch Errors
true # to ignore error, or: some_command_that_might_fail || fallback_to_this_other_command Recently I’ve had a lot of trouble with “set -e”. For example this prints “a”, as you’d expect: set -e myfun() { printf a; false; printf b; } myfun Shell Script Error Handling Badges Ask Question x Dismiss Join the Stack Overflow Community Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes http://david.rothlis.net/shell-set-e/ a minute: Sign up Error handling in BASH up vote 143 down vote favorite 110 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 Shotts, Jr suggests using the following function for error handling in BASH: #!/bin/bash # http://stackoverflow.com/questions/64786/error-handling-in-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 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 program's robustness. That is, the http://linuxcommand.org/wss0150.php program's ability to handle situations in which something goes wrong. Exit status As you recall from http://unix.stackexchange.com/questions/81457/trapping-errors-in-command-substitution-using-o-errtrace-ie-set-e previous lessons, every well-written program returns an exit status when it finishes. If a program finishes successfully, the 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 is also important that your scripts return a meaningful exit error handling 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 the files in that directory. That's the intended behavior. But what happens if the directory bash error handling 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>&2 exit 1 fi In this version, we examine the exit status of the cd command and if it's not zero, we print an error message on standard error and termi here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta 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 Unix & Linux Questions Tags Users Badges Unanswered Ask Question _ Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute: Sign up Here's how it works: Anybody can ask a question Anybody can answer The best answers are voted up and rise to the top Trapping errors in command substitution using “-o errtrace” (ie set -E) up vote 11 down vote favorite 7 According to this ref manual: -E (also -o errtrace) If set, any trap on ERR is inherited by shell functions, command substitutions, and commands executed in a subshell environment. The ERR trap is normally not inherited in such cases. However, I must be interpreting it wrongly, because the following does not work: #!/usr/bin/env bash # -*- bash -*- set -e -o pipefail -o errtrace -o functrace function boom { echo "err status: $?" exit $? } trap boom ERR echo $( made up name ) echo " ! should not be reached ! " I already know simple assignment, my_var=$(made_up_name), will exit the script with set -e (ie errexit). Is -E/-o errtrace supposed to work like the above code? Or, most likely, I misread it? bash command-substitution share|improve this question edited Jul 2 '13 at 18:03 asked Jul 2 '13 at 10:06 dgo.a 244312 2 This is a good question. Replacing echo $( made up name ) with $( made up name ) produces the desired behaviour. I don't have an explanation though. –iruvar Jul 2 '13 at 16:24 I don't know about bash's -E but I do know that -e only effects a shell exit if the error results from the last command in a pipeline. So your var=$( pipe ) and $( pipe ) examples would both represent pipe endpoints whereas pipe > echo would not. My man page says: "1. The f