sections in this module City College of San Francisco - CS160B
Unix/Linux Shell Scripting
Module: Conditionals
module list

The exit status

Every time you run a Linux command, it sets an exit status. The exit status is returned to the parent (in this case your shell or shell script) to indicate whether the command succeeded or failed. The exit status is a small [one-byte] integer. For our purposes, the exit status has two values

Of course, there are many values. In fact, the actual value of the exit status returned by standard Linux commands indicates the type of error that occurred. For the purposes of shell scripting, however, all we care about is success or failure.

When you run a command in the shell, the exit status of the command is saved in the variable $? . Note that $? changes with each command you run, so if you want to examine it, you must do so immediately after the command in question is executed.

The exit status has nothing to do with standard output. Standard output is data that a process writes, as if to a file. The exit status is returned directly from the child process to its parent (it is the return value of the parent's wait() system call). 

Some of us may not have known about the exit status until now. However, you have seen it in action often:

-bash$ cat xxx
cat: Cannot open xxx: No such file or directory

In this example, cat got an error when it tried to open the file xxx. It returned the error using its exit status, which we can see if we immediately examine the exit status variable $?

-bash$ echo $?

This exit status indicates failure because it is not zero. Since cat is a standard system utility, its value also indicates a particular error, in this case (from the file /usr/include/asm-generic/errno-base.h on linux)

#define ENOENT      2   /* No such file or directory    */

Your shell scripts could interpret these error codes, but there is no reason to. If you need to perform an operation and you get an error, the only thing you can do is to give the user as much information as you can, then either go around the problem or give up. For this, simply recognizing an error occurred is usually sufficient.

The only value you should compare the exit status ($?) to is zero. Success or failure is sufficient information for most shell-scripting purposes.

What constitutes failure?

The meaning of failure is program-specific, but usually makes good sense. In the case of our cat command, success means each file given on the commandline was able to be cat-ed successfully. Let's look at a few other common programs and what an exit status of success means:

command success means
ls a a could be listed (it exists, and listing it did not produce an error)
grep pat file1 file1 could be opened and read and the pattern pat was found (at least once)
cp a b the copy succeeded (a existed and could be read; b existed and could be copied into or over)
id u the user u existed

Note that it can be difficult to discern the exact error that occurred. For example, if we execute the command

grep 'pat' file1 2>/dev/null

in our shell script, and 'throw away' the error message so as to not confuse the user, there are at least three sources of failure exit status:

If you need to distinguish between these errors, your shell script would have to first check that file1 existed and was readable, then invoke the grep command. You would also have to test pat to ensure the regular expression was valid. Once these two possible sources of error have been removed, if an error resulted, pat could not be found in file, and our shell script can assume that and output an appropriate error message.

Setting the exit status

The exit status is set when a program invokes the _exit system call. Its single argument is the exit status. This is accomplished from your shell script by invoking the exit command:

exit N

where N is the exit status you wish to set. Unless you are able to set the exit status to indicate the true Linux error code, shell scripts should only use 0 (success) or 1 (failure) as an exit status. 

Every shell program should set the exit status when it exits. If you do not set it, it is set to the exit status of the last command executed in your shell script. 

Negating the exit status

The constructs if and while check whether a command succeeds in order to make a decision. It can be more useful to make a decision based on whether a command fails. You can negate the exit status of a command after it runs by simply prefixing ! to the command. (When testing this at the command-line, you should place a space after the ! . Otherwise it will be interpreted as a history substitution:)

$ cat xxx
cat: xxx: No such file or directory
$ echo $?
$ ! cat xxx
cat: xxx: No such file or directory
$ echo $?

Prev This page was made entirely with free software on Linux:  
Kompozer and LibreOffice

Copyright 2016 Greg Boyd - All Rights Reserved.