On Jul 21, 2009, at 8:53 AM, Andreas Schwab wrote:
Lynn Kerby <l...@kerbit.net> writes:
Use of the '-a' option to the builtin test command fails to
produce the correct result when used with negation. The specific
error the case where the file exists and a "test ! -a file" is
executed. If the script is changed to use '-e' for file
existence the result is correct as expected. If the script is
modified to place parenthesis around the '-a file' expression,
the result is also correct.
This is not a bug, but consistent with the POSIX rules. Better avoid
the (nonstandard) -a unary operator and use -e instead. The problem
is
that -a is also a binary operator, and POSIX says that if test is
called
with three arguments and the second argument is a binary operator it
should be parsed as such.
See
<http://opengroup.org/onlinepubs/9699919799/utilities/test.html#tag_20_128_05
>
for details.
Andreas.
--
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276
4ED5
"And now for something completely different."
Thanks, I hadn't read the Open Group test command doc. However, I
find the doc inconsistent on this matter when read in its entirety.
For starters, POSIX doesn't allow for the use of '-a' as a unary
operator (according to the RATIONALE section this is because mere
humans will be confused and should use '-e' instead). In that context,
the parsing of 3 arguments to test could proceed on the assumption
that any '-a' option in the middle would be an attempt to perform a
binary operation. The GNU bash and test command do support the
historical '-a' unary operator usage as a unary operator, so its hard
to justify this behavior as POSIX conformant IMO. It might be, but it
is pretty clearly wrong.
Secondly, down in the RATIONALE section the document states:
In evaluating these more complex combined expressions, the following
precedence rules are used:
•The unary primaries have higher precedence than the algebraic
binary primaries.
•The unary primaries have lower precedence than the string binary
primaries.
•The unary and binary primaries have higher precedence than the
unary string primary.
•The ! operator has higher precedence than the -a operator, and the
-a operator has higher precedence than the -o operator.
•The -a and -o operators are left associative.
•The parentheses can be used to alter the normal precedence and
associativity.
So if I'm reading that corrrectly, the '!' operator is supposed to
have a higher precedence than the '-a' operator in complex
expressions. Simply adding a "-a 1" to the expression (resulting in
" ! -a file -a 1") causes a different parsing behavior. It seems that
the 3 argument processing rules for the test command violate this by
having the negation test ordered after binary primaries. The rules
for 2 and 4 argument parsing clearly handle negation first.
I still consider this a bug, since this is caused by an ambiguity (at
some level) in a non-POSIX defined operator. Blaming it on a POSIX
defined argument processing rule doesn't really apply here. Whatever
the disposition, I'm going to be modifying this bunch of scripts
(inherited) to use the '-e' unary operator for existence tests.
Lynn Kerby