UNIX shell commands return exit statuses or exit codes upon completion, irrespective of whether successful or not. In UNIX, an exit status of 0 indicates successful execution of a command and a non-zero exit status indicates a failure. Some shells (e.g. ksh93) document the various exit statuses and their meanings. So, checking exit statuses of commands is typically done in programs like shell scripts to decide further action to be taken by the script.

However, piped commands or a pipeline (cmd A | cmd B), add a twist to checking exit statuses as by default, most UNIX shells adhere to the POSIX requirement of returning the exit status of the last command in the pipe. Refer the example below:

So, checking the exit status of a pipeline as in the above example will cause problems for your script if any of the piped commands other than the last command throw an error. Given below are two solutions (using ksh93 and bash) to solve this problem and ensure a valid exit status check for a pipeline:

SOLUTION 1: Using ksh93 and the pipefail option

The Korn Shell 1993 version ‘g’ point release (ksh93g) introduced a pipefail option which ensures that the exit status of a pipeline will be that of the first command in the pipe that has failed (of course, the exit status of the pipeline will be 0 if all commands in the pipe succeed). Unfortunately, ksh88 is distributed as the default Korn Shell with most UNIX systems (with all Solaris versions I believe) because ksh93 is owned by Lucent and AT&T and there were licensing restrictions. Refer I (Q.14) and III (Q.8) of the Korn shell FAQs at http://kornshell.com/doc/faq.html

SIGPIPE is a signal sent to a process (that causes the process to terminate) that writes to a pipe when there is nothing to read from the pipe. If you use any of the above mthods to check the exit status of a pipeline and a SIGPIPE is received by one of the commands in the pipeline, then your exit status may not correlate with the success/failure of the pipeline.

For example, in the command,

ls -lrt | head -1

“ls -lrt” writes to a pipe and “head -1” reads from that pipe. Now, “head -1” only requires the first line from the pipe and as soon as it gets it, it terminates and sends a SIGPIPE (signal 13) to “ls -lrt” causing “ls -lrt” to terminate with a non-zero exit code.

NOTE:

(1) The how-to above describes how I implemented something and may not be the only method of implementation.

(2) Your rating of this post will be much appreciated. Also, feel free to leave comments.