[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: builtin test command file existence fails with negation

From: Lynn Kerby
Subject: Re: builtin test command file existence fails with negation
Date: Tue, 21 Jul 2009 10:42:24 -0700

On Jul 21, 2009, at 8:53 AM, Andreas Schwab wrote:

Lynn Kerby <lfk@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.

<http://opengroup.org/onlinepubs/9699919799/utilities/test.html#tag_20_128_05 >
for details.


Andreas Schwab, schwab@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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]