Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [73]

By Root 984 0

... ]

[ else

statements-if-all-else-fails ]

fi

(The square brackets indicate optional parts; they are not typed literally.) The shell's syntax is based loosely on that of Algol 68, which is the language that Steven Bourne, the author of the V7 shell, really admired. It is most notable for the use of opening and closing keywords to bracket statement groups, instead of the begin and end delimiters of Algol 60 and Pascal, or the { and } popularized by C and used almost universally in other programmable Unix tools.

In the case at hand, you can probably guess how this works: the shell runs the first group of statements between the if and the then. If the last statement executed exits successfully, it runs statements-if-true-1. Otherwise, if an elif is present, it tries the next group of statements. If the last one exits successfully, it runs statements-if-true-2. It continues in this fashion until it encounters a command that exits successfully, running the corresponding group of statements.

If none of the if or elif statements is true, and an else clause is present, it executes statements-if-all-else-fails. Otherwise, it does nothing. The exit status of the entire if...fi statement is that of the last command executed following a then or else. If none was executed, the exit status is 0. For example:

if grep pattern myfile > /dev/null

then

... Pattern is there

else

... Pattern is not there

fi

grep exits with a 0 status if myfile contains pattern. It exits with a value of 1 if no line matched the pattern, and with a value greater than 1 if there was an error. Based on grep's exit status, the shell chooses which group of statements to execute.

Logical NOT, AND, and OR

Sometimes it's easier to phrase your tests in the negative: "if John is not at home, then ..." The way to do this in the shell is to precede a pipeline with an exclamation mark:

if ! grep pattern myfile > /dev/null

then

... Pattern is not there

fi

POSIX introduced this notation in the 1992 standard. You will likely see older shell scripts that use the colon (:) command, which does nothing, to handle this kind of case:

if grep pattern myfile > /dev/null

then

: # do nothing

else

... Pattern is not there

fi

Besides just testing the inverse of things with !, you will often want to test multiple subconditions, with AND and OR constructs. ("If John is home, and he isn't busy, then ..."). When the operator && separates two commands, the shell executes the first one. If it exits successfully, the shell executes the second one. If that exits successfully too, then the entire group is considered to have succeeded:

if grep pattern1 myfile && grep pattern2 myfile

then

... myfile contains both patterns

fi

In contrast, the || operator is used when you want to test if one condition or the other is true:

if grep pattern1 myfile || grep pattern2 myfile

then

... One or the other is present

fi

Both of these are short-circuit operators, meaning that the shell stops evaluating commands as soon as it can determine the truth-value of the entire group. For example, in command1 && command2, if command1 fails, then there is no way the whole thing could be true, so command2 never executes. Similarly for command1 || command2: if command1 succeeds, there is no reason to execute command2.

Don't try to be overly "terse" and use && and || to replace the if statement. We have little objection to something short and simple, like this:

$ who | grep tolstoy > /dev/null && echo tolstoy is logged on

tolstoy is logged on

This runs who | grep ..., and if that succeeds it prints the message. However, we have seen vendor shell scripts use constructs like this:

some_command && {

one command

a second command

and a third command

}

The braces serve to group all the commands together, which are executed only if some_command succeeds. This would be much more cleanly written using a simple if:

if some_command

then

one command

a second command

and a third command

fi

The test Command

The aptly named test command exists to perform

Return Main Page Previous Page Next Page

®Online Book Reader