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