Exit status

Exit Status
Every Unix program returns a numeric exit code when it terminates. By long-standing convention, a successful termination is indicated by an exit status of zero. Non-zero exit codes indicate failure. "1" is the most commonly used exit code for a failed program, but extra codes can be useful in some circumstances. For example grep searches files or standard input for text patterns; it returns 0 if it finds the pattern, 1 if it does not, and 2 if it cannot understand the syntax of the search term. In this case it makes good sense to distinguish a genuine failure of the program from a mere failure to find something that is not there to be found.

Source of the exit code
Programs written in C or C++ normally exit by calling the exit function. This takes an integer argument which corresponds to the exit status. The exit status code is one of the "two last words" that the kernel returns to the parent process after notifying it that its child has exited. The other word is always zero if the process has exited by itself (successfully or otherwise); if it has been crashed by a signal, the signal's ID number forms the second word. In this case, the exit code will be set to the signal number plus one (i.e. a non-zero value) to indicate that this was not a successful exit.

The kernel will not delete the process's task structure until its parent has received the last words by calling one of the wait functions. If a badly-written program fails to do this, its child cannot fully die and becomes a "zombie", hanging around until the next reboot.

Exit codes and conditions
Shell scripts frequently execute conditional statements based on the exit codes of programs that they have run. In bash, simple conditions can be set up by linking two commands with && (boolean and) or || (boolean or). The execution of the second statement then becomes conditional on the success of the first. A boolean and means that the second statement will be executed only if the first statement succeeds. Conversely, boolean or will allow the statements to act as alternatives: if the first one fails, the second will be run.

More complicated conditions are also possible by using the if (condition) then;...fi construction. It is very common for the governing condition in such cases to be the exit status of a command.