GNU bug report logs - #15278
test: favor -a as binary op, with three arguments and !

Previous Next

Package: coreutils;

Reported by: Eric Blake <eblake <at> redhat.com>

Date: Thu, 5 Sep 2013 17:43:01 UTC

Severity: normal

Tags: confirmed, fixed

Merged with 33097

Done: Bernhard Voelker <mail <at> bernhard-voelker.de>

Bug is archived. No further changes may be made.

Full log


Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Eric Blake <eblake <at> redhat.com>
Cc: bug-coreutils <at> gnu.org, bug-bash <at> gnu.org, kneufeld <at> gmail.com
Subject: Re: -a vs -e
Date: Thu, 05 Sep 2013 10:45:15 -0600
[Message part 1 (text/plain, inline)]
[moving to the coreutils list, as coreutils has a bug here]

On 09/05/2013 10:33 AM, Eric Blake wrote:
> On 09/04/2013 11:06 PM, kneufeld <at> gmail.com wrote:
>> According to the man page, [ -a ] and [ -e ] should have the same behaviour.
> 
> Not a bug.  -a behaves like -e only when it is unambiguously parsed as a
> unary operator, because it is bash extension as a unary operator.
> 
>>
>> -a file
>>     True if file exists.
>> ...
>> -e file
>>     True if file exists.
>>
>> $ touch stuff.txt
>> $ [ -a stuff.txt ]; echo $?
>> 0
>> $ [ -e stuff.txt ]; echo $?
>> 0
>> $ [ ! -e stuff.txt ]; echo $?
>> 1
>> $ [ ! -a stuff.txt ]; echo $?
>> 0     # what?
> 
> But _this_ is an instance where -a is parsed as a binary operator (ie.
> it was parsed as "\( ! \) -a \( stuff.txt \)", not "! \( -a stuff.txt
> \)".  -a as a binary operator is required by POSIX for XSI, therefore it
> takes priority over -a as a unary operator as a bash extension.
> 

The POSIX wording states for 3-argument tests
(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html):

• If $2 is a binary primary, perform the binary test of $1 and $3.
• If $1 is ’!’, negate the two-argument test of $2 and $3.
• If $1 is ’(’ and $3 is ’)’, perform the unary test of $2.

The first two bullets both apply to your situation, but it can be
assumed that the ordering of the bullets is significant.  Why?  Because
"test \( = \)" is a case of both the first and third bullet applying,
and on that case, both bash and coreutils agree that it returns false
(3-argument string comparison of different strings) rather than true
(parenthesized 1-argument test of non-empty =).

Coreutils therefore should fix its test to favor binary -a over unary
-a, when there are three arguments and the first is !.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

[signature.asc (application/pgp-signature, attachment)]

This bug report was last modified 6 years and 266 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.