bug-bash
[Top][All Lists]
Advanced

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

Re: Bug in parameter parsing of test built-in


From: Eric Blake
Subject: Re: Bug in parameter parsing of test built-in
Date: Mon, 27 Jul 2015 09:39:52 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0

On 07/27/2015 07:37 AM, Alexander Sulfrian wrote:
> Hi,
> 
> I discovered a bug in the parameter parsing of the test built-in:

No, you merely (re-)discovered that '-a' and '-o' are inherently
ambiguous as operators, and should never be used with test.  Even POSIX
recommends against their use, and says you should use separate test
invocations separated by || or && to express what you really meant.

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html

    The XSI extensions specifying the -a and -o binary primaries and the
'(' and ')' operators have been marked obsolescent. (Many expressions
using them are ambiguously defined by the grammar depending on the
specific expressions being evaluated.) Scripts using these expressions
should be converted to the forms given below. Even though many
implementations will continue to support these obsolescent forms,
scripts should be extremely careful when dealing with user-supplied
input that could be confused with these and other primaries and
operators. Unless the application developer knows all the cases that
produce input to the script, invocations like:

    test "$1" -a "$2"

    should be written as:

    test "$1" && test "$2"

    to avoid problems if a user supplied values such as $1 set to '!'
and $2 set to the null string. That is, in cases where maximal
portability is of concern, replace:

    test expr1 -a expr2

    with:

    test expr1 && test expr2

    and replace:

    test expr1 -o expr2

    with:

    test expr1 || test expr2

    but note that, in test, -a has higher precedence than -o while "&&"
and "||" have equal precedence in the shell.


> 
>     $ test -n '<' -a true
>     -bash: test: too many arguments

That's because bash is parsing it as:
test \( -n \< -a \) true
which is indeed syntactically invalid.  You could manually add ():
test \( -n \< \) -a true
to force the precedence you appear to want, but better would be avoiding -a:
test -n \< && test true

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

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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