[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
signature.asc
Description: OpenPGP digital signature