John Wenker <jjw@pt.com> wrote:
The following construct _always_ evaluates true, regardless of
whether the file exists or not.
if [ ! -a file ]; then
echo "This line always prints no matter what."
else
echo "This line never prints."
fi
-a can act as a prefix unary operator, or an infix binary "and"
operator. When it appears as the second of three arguments (not
counting "]") in a test, it's treated as a binary operator, even if
the first argument is "!". So in this case, "!" is test, and as a
single string it's only tested for non-emptiness, and so is considered
true. Likewise for "file". Since both subtests are true, the
combined "and" test is also true.
There are a few different ways to get the behavior you want. You
could use "[ ! \( -a file \) ]" or "! [ -a file ]", although those are
not portable to some other shells. (The behavior of a test is
generally more predictable when there are fewer arguments, so I'd go
with the second of those two, since it pulls the "!" outside the test
and leaves only two arguments for the test to examine.) You could
also remove "!" and switch your "then" and "else" clauses, which works
with any shell.