[Chapter 46] 46.9 If Command Doesn't Return a Status, Test the Error Messages
Author: Jerry Peek, Tim O'Reilly & Mike Loukides
Date: 1998-08-04T21:55:43Z

#

| Chapter 46 Shell Script Debugging and Gotchas |

## 46.9 If Command Doesn't Return a Status, Test the Error Messages

UNIX commands should return a zero exit status (44.7) if they succeed or a non-zero status if they fail. Not all commands do. For example, here's a log I found of a test I did back in 1985 to the 4.3BSD version of touch (21.7):

>     $ touch /tmp
>     touch: /tmp: can only touch regular files
>     $ echo $?

>     $ touch -f /usr/src/usr.bin/touch.c
>     touch: /usr/src/usr.bin/touch.c: couldn't chmod: Not owner
>     $ echo $?

>     $ touch -z
>     touch: bad option -z
>     $ echo $?

Because the status was always zero, as if the command had succeeded, my shell scripts couldn't test the exit status for failure. A workaround is to make your own shell script version of touch (maybe call it mytouch)-or to put code like this into a shell script where you need to run touch: [1]

> [1] Thanks to Richard Doty for this idea and the section of the shell script I've shown here.

    2>&1
    # RUN touch ON THE COMMAND LINE ARGUMENTS (INCLUDING ANY OPTIONS).
    # MERGE stderr ONTO stdout AND TEST FOR ERROR MESSAGES:
    out=`/bin/touch "$@" 2>&1`
    case "$out" in
    "")                                   exitstat=0;;
    *bad\ option)                         exitstat=l ; echo "$out" 1>&2;;
    *does\ not\ exist)                    exitstat=3 ; echo "$out" 1>&2;;
    *can\ only\ touch\ regular\ files*)   exitstat=4 ; echo "$out" 1>&2;;
    *couldn\'t\ chmod)                    exitstat=5 ; echo "$out" 1>&2;;
    *couldn\'t\ chmod\ back)              exitstat=6 ; echo "$out" 1>&2;;
    *cannot\ touch)                       exitstat=7 ; echo "$out" 1>&2;;
    *)                                    exitstat=10; echo "$out" 1>&2;;
    esac
    exit $exitstat

That code handles many of the error exits; other errors get an exit status of 10. You could simplify the code to return a status of 1 on any error. On the other hand, it would be easy to expand that code to cover any possible (or interesting) error output. Article 27.19 shows how to get a list of many of the possible error messages; you can also see the errors by making some typical mistakes like unreadable or unwritable filenames.

That code won't work everywhere. The command you're running might write text to standard output that you don't want mixed together with error messages (on the standard error). Or, worse, some vendors' versions of some commands write errors to the standard output! Still, this technique should give you a good start on working around badly behaved UNIX commands.

- JP

46.8 Test Built-In Commands for Failure |  | 46.10 A Portable echo Command