## 35.12. Exit Status of Unix Processes

When a Unix process (command) runs, it can return a numeric status value to the parent process that called (started) it. The status can tell the calling process whether the command succeeded or failed. Many (but not all) Unix commands return a status of zero if everything was okay and nonzero (1, 2, etc.) if something went wrong. A few commands, such as grep and diff, return a different nonzero status for different kinds of problems; see your online manual pages (or just experiment!) to find out.

The Bourne shell puts the exit status of the previous command in the question mark (`?`) variable. You can get its value by preceding it with a dollar sign (`$`), just like any other shell variable. For example, when cp copies a file, it sets the status to 0. If something goes wrong, cp sets the status to 1:

>     $ cp afile /tmp
>     $ echo $?
>     0
>     $ cp afiel /tmp
>     cp: afiel: No such file or directory
>     $ echo $?
>     1

In the C shell, use the status variable instead (tcsh supports both):

>     % cp afiel /tmp
>     cp: afiel: No such file or directory
>     % echo $status
>     1
>     tcsh> cp afiel /tmp
>     cp: afiel: No such file or directory
>     tcsh> echo $status
>     1

Of course, you usually don't have to display the exit status in this way, because there are several ways (Section 35.13, Section 35.14, Section 35.15) to use the exit status of one command as a condition of further execution.

Go to http://examples.oreilly.com/upt3 for more information on: true, false

Two simple Unix utilities do nothing but return an exit status. true returns a status of 0 (zero); false returns 1 (one). There are GNU versions on the web site -- and no, they don't have any amazing extra features. `;-)`

bash and zsh have a handy way to reverse the status of a command line: put an exclamation point (`!`) before it. Let's look at a simple example (of course, you'd use `!` with something besides true or false):

>     bash$ true
>     bash$ echo $?
>     0
>     bash$ ! true
>     bash$ echo $?
>     1
>     bash$ false
>     bash$ echo $?
>     1
>     bash$ ! false
>     bash$ echo $?
>     0

tcsh and zsh have a handy feature for work with exit statuses. If you set the tcsh shell variable printexitvalue or the zsh shell option PRINT_EXIT_VALUE , the shell will print the exit status of any program that doesn't return zero. For example:

>     zsh$ setopt printexitvalue
>     zsh$ grep '<title>' 0001.sgm
>     <title>Too Many Arguments for the Command Line</title>
>     zsh$ grep '<title>' 0000.sgm
>     grep: 0000.sgm: No such file or directory
>     zsh: exit 2     grep <title> 0000.sgm
>     zsh$ grep '<ttle>' 0001.sgm
>     zsh: exit 1     grep <ttle> 0001.sgm

>     tcsh% set printexitvalue
>     tcsh% true
>     tcsh% false
>     Exit 1

You can't test the exit status of a background job in the Bourne shell unless you use the wait command to wait for it (in effect, to bring the job out of the background). Pipelines, however, return the exit status of the last program in the pipeline.

-- JP

Copyright © 2003 O'Reilly & Associates. All rights reserved.