Linux Bash Script Error Handling
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
Shell Script Exit Code
of your scripts. The difference between a good program and a poor shell script exit on error one is often measured in terms of the program's robustness. That is, the program's ability to handle situations bash if exit code in which something goes wrong. 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
Linux Kernel Error Codes
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 status when they finish. I once had a Unix system
Bash If Exit Code Not 0
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 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
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 bash trap ads with us Unix & Linux Questions Tags Users Badges Unanswered Ask Question _ Unix & Linux
Exit Bash Shell
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: 1>&2 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 How to catch an error in a linux bash script? up vote 5 down vote favorite 1 http://linuxcommand.org/wss0150.php I made the following script: # !/bin/bash # OUTPUT-COLORING red='\e[0;31m' green='\e[0;32m' NC='\e[0m' # No Color # FUNCTIONS # directoryExists - Does the directory exist? function directoryExists { cd $1 if [ $? = 0 ] then echo -e "${green}$1${NC}" else echo -e "${red}$1${NC}" fi } # EXE directoryExists "~/foobar" directoryExists "/www/html/drupal" The script works, but beside my echoes, there is also the output when cd $1 fails on execution. testscripts//test_labo3: line 11: cd: ~/foobar: No such file or directory Is it possible to catch this? http://unix.stackexchange.com/questions/97101/how-to-catch-an-error-in-a-linux-bash-script bash shell shell-script error-handling share|improve this question edited Oct 22 '13 at 22:58 Gilles 372k696761127 asked Oct 22 '13 at 10:29 Thomas De Wilde 28114 Just an FYI, you can also do this a lot simpler; test -d /path/to/directory ( or [[ -d /path/to/directory ]] in bash ) will tell you whether a given target is a directory or not, and it will do it quietly. –Patrick Oct 22 '13 at 12:36 @Patrick, that just tests if it's a directory, not if you can cd into it. –Stéphane Chazelas Oct 22 '13 at 12:54 @StephaneChazelas yes. The function name is directoryExists. –Patrick Oct 22 '13 at 13:57 add a comment| 5 Answers 5 active oldest votes up vote 4 down vote accepted Your script changes directories as it runs, which means it won't work with a series of relative pathnames. You then commented later that you only wanted to check for directory existence, not the ability to use cd, so answers don't need to use cd at all. Revised. Using tput and colours from man terminfo: #!/bin/bash -u # OUTPUT-COLORING red=$( tput setaf 1 ) green=$( tput setaf 2 ) NC=$( tput setaf 0 ) # or perhaps: tput sgr0 # FUNCTIONS # directoryExists - Does the directory exist? function directoryExists { # was: do the cd in a sub-shell so it doesn't change our own PWD # was: if errmsg=$( cd -- "$1" 2>&1 ) ; then if [ -d "$1" ] ;
the ability to anticipate and respond to error situations gracefully and without anything breaking. Dave explores some of the basic shell script error-handling options. I http://www.linuxjournal.com/magazine/work-shell-handling-errors-and-making-scripts-bulletproof realize I've been playing a bit fast and loose with my shell scripts https://www.howtoforge.com/detailed-error-handling-in-bash over the last few months, because I haven't talked about how to ensure that error conditions don't break things. If you read the Letters section in Linux Journal, you know I haven't covered this topic because, well, you have covered it for me! This topic ranges from the simple to exit code the sophisticated, so let's start with a basic test: the return status after an application or utility is invoked. The Magical $? Sequence Different shells have different return status indicators (the C shell, for example, uses $status), but the most basic is Bash/the Bourne shell, which is what we've focused on since I started writing Work the Shell, and it uses $?. Here's shell script exit a quick example: #!/bin/sh mkdir / echo "return status is $?" mkdir /tmp/foobar echo "return status is $?" rmdir /tmp/foobar echo "return status is $?" rmdir /tmp echo "return status is $?" exit 0 Run this, and you can see the difference between commands that succeed and those that fail: mkdir: /: Is a directory return status is 1 return status is 0 return status is 0 rmdir: /tmp: Not a directory return status is 1 You can see that when invoking mkdir or rmdir with an error condition, they output an error and—the important part—the $? return status is nonzero. In fact, check out the man page for a typical command like mkdir, and you'll see: “DIAGNOSTICS: The mkdir utility exits 0 on success, and >0 if an error occurs.” In a perfect world, the >0 return code would actually tell you what happened, but although that's true with the functions accessible via software, it's not true for the shell. On the other hand, it's still helpful to explore how to make a shell function that does error handling too. Here's a basic example function: makedirectory() {
this page Detailed Error Handling In Bash Summary The database The mechanism Caveat Invoking the error handler The full script Usage example References Detailed Error Handling In Bash by Willem Bogaerts, application smith at Kratz Business Solutions Summary Shell scripts are often running as background processes, doing useful things without running in a visible shell. Think, for example, of cron jobs or scripts that are fired from a program on a web server. To write such scripts can be quite painful, as all errors occur out of sight as well. Off course you can make use of a log file, but the ideal level of logging is hard to find. You often log way too much when the script is running fine and way too little when it unexpectedly fails. While log files can hold a lot of information, finding the relevant information is a bit trickier. My solution is to log only the errors with all the details to a small database. This database contains tables for the message, the corresponding stack trace and the important environment variables. I have chosen for an SQLite database in this howto, but the same principle works with other databases as well. The database SQLite needs some settings to work as I expect it to, and these settings can be put in an initializing script. These settings include the error behaviour of SQLite itself and its foreign key handling: .bail ON .echo OFF PRAGMA foreign_keys = TRUE; Off course, we also need a database and I do not want to rely on one to exist. Therefore, the first thing the bash script will do is to run an SQL "revive" script on the database file: if the database did not exist, it will be created and if it did, it will do nothing: CREATE TABLE IF NOT EXISTS ErrorLog (intErrorLogId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, strMessage TEXT NOT NULL, tstOccurredAt DATE NOT NULL DEFAULT(CURRENT_TIMESTAMP) ); CREATE INDEX IF NOT EXISTS idxELOccurredAt ON ErrorLog(tstOccurredAt); CREATE TABLE IF NOT EXISTS ErrorStackTrace (intErrorStackTraceId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, intErrorLogId INTEGER NOT NULL, strSourceFile TEXT NOT NULL, strFunction TEXT NOT NULL, intLine INTEGER NOT NULL, FOREIGN KEY(intErrorLogId) REFEREN