[Top][All Lists]

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

Re: error in expression evaluation

From: Eric Blake
Subject: Re: error in expression evaluation
Date: Fri, 22 Feb 2008 08:04:46 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20071031 Thunderbird/ Mnenhy/

Hash: SHA1

According to Bernhard Bablok on 2/22/2008 4:48 AM:
| Description:
| The following code produces an error (second if-statement):
| #!/bin/bash
| if [ '(' != ',' ]; then
|    echo "'(' != ',' works :-)"
| fi
| if [ 'a' != 'b' -a '(' != ',' ]; then
|    echo "'a' != 'b' -a '(' != ',' does not work :-("
| fi
| It seems that the parser does not like the "(" after an "-a" in a compound
| expression.

Not a bug.  POSIX is quite clear that using more than 4 arguments to [ is
inherently non-portable, because of the possibility of ambiguous parses.
In your case, the ambiguity is between "'(' != ," being a three-argument
test with the binary operator !=, and "'('" starting an (unterminated)
parenthesized test.

POSIX highly encourages you to avoid all use of 'test -a', because of this
and other ambiguity problems it creates.  And in general, when testing
arbitrary strings for (in)equality, it is better to use a prefix to
guarantee that the string cannot be confused with an operator (consider [
'(' = ')' ] - is it the 3-argument test for equality between the two
strings resulting in false, or the parenthesized 1-argument test for the
middle string being non-empty resulting in true?).  Your expression would
be more portable as:

[ a != b ] && [ x'(' != x, ]

| Fix:
| Workaround: don't use a compound expression,

Yes - that is the only portable way to use [.

| use a second if-statement within
| the first if-statement.

Or use && between two invocations of test.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org


reply via email to

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