Use the operators for logical AND (-a)
and OR
(-o)
to combine more than one test in an expression. For
example:
if [ -r $FILE -a -w $FILE ]
will test to see that the file is both readable and writable.
All the file test conditions include an implicit test for existence, so you don’t need to test if a file exists and is readable. It won’t be readable if it doesn’t exist.
These conjunctions (-a
for AND
and -o
for OR) can be used for all
the various test conditions. They aren’t limited to just the file
conditions.
You can make several and/or conjunctions on one statement. You
might need to use parentheses to get the proper precedence, as in
a and (b or c)
, but if you use
parentheses, be sure to escape their special meaning from the shell by
putting a backslash before each or by quoting each parenthesis. Don’t
try to quote the entire expression in one set of quotes, however, as
that will make your entire expression a single term that will be treated
as a test for an empty string (see Testing for String Characteristics).
Here’s an example of a more complex test with the parentheses properly escaped:
if [ -r "$FN" -a ( -f "$FN" -o -p "$FN" ) ]
Don’t make the assumption that these expressions are evaluated in quite the same order as in Java or C language. In C and Java, if the first part of the AND expression is false (or the first part true in an OR expression), the second part of the expression won’t be evaluated (we say the expression short-circuited). However, because the shell makes multiple passes over the statement while preparing it for evaluation (e.g., doing parameter substitution, etc.), both parts of the joined condition may have been partially evaluated. While it doesn’t matter in this simple example, in more complicated situations it might. For example:
if [ -z "$V1" -o -z "${V2:=YIKES}" ]
Even if $V1
is empty,
satisfying enough of the if
statement
that the second part of the condition (checking if $V2
is empty) need not occur, the value of
$V2
may have already been modified
(as a side-effect of the parameter substitution for $V2
). The parameter substitution step occurs
before the -z
tests are made.
Confused? Don’t be…just don’t count on short circuits in your
conditionals. If you need that kind of behavior, just break the if
statement into two nested if
statements.
Appendix C for more on command-line processing
3.144.250.169