Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Jan 2016 08:25:27 -0900
From:      "CK" <nibbana@gmx.us>
To:        <freebsd-questions@freebsd.org>
Subject:   Sh-test, bug or not?
Message-ID:  <0Lg5kl-1ZnW3s29Zj-00pbLI@mail.gmx.com>

next in thread | raw e-mail | index | archive | help
> On 15/01/2016 04:32, CK wrote:
> > If you have authoritative knowledge on the subject,
> > please state if this functionality is correct:
> >
> > $ [ ! "" -a "" ] && echo pass || echo fail
> > pass
> > $ [ ! 11 -a "" ] && echo pass || echo fail
> > pass
> >
> > The "-a" operator binds stronger than the "!" operator.
> > Intuition based on functionality in awk/C would suppose
> > that the "!" operator would bind stronger than the "-a"
> > operator, especially since "-a" does in fact have higher
> > precedence than the "-o" operator, as in awk/C.
> >
> > In order to make it work as "expected", it gets ugly:
> >
> > $ [ ! "" -a "" ] && echo pass || echo fail
> > pass
> > $ [ \( ! "" \) -a "" ] && echo pass || echo fail
> > fail
> >
> > $ [ ! 11 -a "" ] && echo pass || echo fail
> > pass
> > $ [ \( ! 11 \) -a "" ] && echo pass || echo fail
> > fail
> >
> > I never noticed this in 20 years, so I don't know if it always
> > worked this way, or if something changed in my upgrade from
> > 4.11 to 9.3.
>
> --
> REPLY#1
> #######
> I think that while unexpected in comparison to other languages which
> have inherited C-like operator precedence rules, this is according to
> the POSIX standard for test(1).  As the man page says:
>
>      The test grammar is inherently ambiguous.  In order to assure a degree
>      of consistency, the cases described in the IEEE Std 1003.2
>      (``POSIX.2''), section D11.2/4.62.4, standard are evaluated
>      consistently according to the rules specified in the standards
>      document.  All other cases are subject to the ambiguity in the
>      command semantics.
>
> and it notes that the ambiguous cases are those involving (), -a and -o.
>
> Your test might be more clearly expressed as:
>
> $ [ ! "" ] && [ "" ] && echo pass || echo fail
> fail
>
> (although I'd recommend the -z and -n operators for testing the
> emptiness / undefinedness or not of strings.)
>
> --
> REPLY#2
> #######
> I would never claim to be an authority, but a quick look at the test(1)
> code shows that although the comments starting line 53 suggest the
> grammar one would expect, there's a special case in main() for an
> expression of exactly four parts starting with "!". The comment on line
> 218 is relevant to your tests.
>
> 217          if (nargc == 4 && strcmp(*t_wp, "!") == 0) {
> 218       /* Things like ! "" -o x do not fit in the normal grammar. */
> 219                  --nargc;
> 220                  ++t_wp;
> 221                  res = oexpr(t_lex(*t_wp));
> 222          } else
> 223                  res = !oexpr(t_lex(*t_wp));
>
> I presume the shells use a version of this code as well. My guess would
> be that this is some sort of kludge going back to the original bourne
> shell, but someone else more knowledgeable than me will have to deal
> with that.

In regards to Reply#1, yes, I did read that previously, but that leaves
the sensibility of the cited functionality open to whatever is most
sensible.  And the current functionality does not seem sensible due
to its apparent senseless incongruity with standard functionality
in most/all other languages, in addition to making simple expressions
more lengthy/tedious/ugly than necessary.  Of course, these were just
examples to demonstrate the functionality.

In regards to Reply#2 - that sure is odd!

$ [ ! "" -a "" ] && echo pass || echo fail
pass
$ [ ! "" -a "" -a "" ] && echo pass || echo fail
fail

Haha ... !!!  You hit the nail on the head!  This is terrible.
Thank you for making that insightful effort to find the real
reason for this functionality - this sure is a strange exception.

May you be free from danger, happy, healthy, and loving with ease.
Submitted 21 hours ago by unixygirl, theravada [/r/Buddhism] :)




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?0Lg5kl-1ZnW3s29Zj-00pbLI>