sections in this module | City
College of San Francisco - CS160B Unix/Linux Shell Scripting Module: Conditionals |
module list |
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
0 - the command succeeded (success)
non-zero - the command failed.
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
-bash$
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 $?
2
-bash$
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:
file1 could not be opened for reading
file1 did not contain any instances of pat
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:)
Prev | This page was made entirely
with free software on Linux: Kompozer and LibreOffice |
Next |