Checking the success of a command in a bash `if [ .. ]` statement

You are making the common mistake of assuming that [ is part of the if statement’s syntax. It is not; the syntax of if is simply

if command; then
    : # ... things which should happen if command's result code was 0
else
    : # ... things which should happen otherwise
fi

One of the common commands we use is [ which is an alias for the command test. It is a simple command for comparing strings, numbers, and files. It accepts a fairly narrow combination of arguments, and tends to generate confusing and misleading error messages if you don’t pass it the expected arguments. (Or rather, the error messages are adequate and helpful once you get used to it, but they are easily misunderstood if you’re not used.)

Here, you want to check the result of the command egrep:

if [ ! -f /opt/apps/SiteScope_backup/sitescope_configuration.zip ] ||
   egrep -i -q "error|warning|fatal|missing|critical" "$File"
then
    echo "testing"
fi

In the general case, command can be a pipeline or a list of commands; then, the exit code from the final command is the status which if will examine, similarly to how the last command in a script decides the exit status from the script.

These compound commands can be arbitrarily complex, like

if read thing
    case $thing in
      '' | 'quit') false;;
      *) true;;
    esac
then ...

but in practice, you rarely see more than a single command in the if statement (though it’s not unheard of; your compound statement with || is a good example!)

Just to spell this out,

if [ egrep foo bar ]

is running [ aka test on the arguments egrep foo bar. But [ without options only accepts a single argument, and then checks whether or not that argument is the empty string. (egrep is clearly not an empty string. Quoting here is optional, but would perhaps make it easier to see:

if [ "egrep" ]; then
    echo "yes, 'egrep' is not equal to ''"
fi

This is obviously silly in isolation, but should hopefully work as an illustrative example.)

The historical reasons for test as a general kitchen sink of stuff the authors didn’t want to make part of the syntax of if is one of the less attractive designs of the original Bourne shell. Bash and zsh offer alternatives which are less unwieldy (like the [[ double brackets in bash), and of course, POSIX test is a lot more well-tempered than the original creation from Bell Labs.

Leave a Comment