On Fri, 14 May 2010 06:57:17 you wrote:
> Le 12/05/2010 07:33, Andrew Clarke a écrit :
> <snip>
>
> > Ok, that's what I was thinking. My original expression was a bit
> > more complex than this:
> >
> > if [[ -n "$list" || ( $# -gt 1 && -t 0 && -t 1 ) ]]; then
>
> well, in the current case, there is no really advantage of using ((
> )) somewhere.
>
True - if it can't be done. The old [[ ]] allows it to be simple without
excessive tokens. I've already learned so much about (( )) and it's
limits - thanks guys
> if you dislike the -gt, you may use > in place, the result will be
> the same :
>
> if [[ -n "$list" || ( $# > 1 && -t 0 && -t 1 ) ]]; then
>
Not quite. compare:
if [[ 3 > 2 ]]; then echo yes; else echo no; fi
if [[ 10 > 2 ]]; then echo yes; else echo no; fi
-gt is arithmetic, > is string. I wonder how many scripts have this
lurking as an occasionally manifested bug?
I am not concerned with using -gt style operators. They keep springing
up in languages (I've most recently seen it in Windows Powershell) and I
have no moral objection to their existence in that syntactical form.
However, I realise that the ( ) in my very first expression is
redundant. I remember a time when [[ ]] did not seem to like more than
one && or || in a row. Back on HP-UX 10 I think, or maybe more recently.
I've had that "workaround" as a habit for a long time too.
> > Where list can be '' or 1
> >
> > the -n "$list" can be substituted with ((list)) as long as the
> > unset value of $list is set to 0 - but then the expression maps to:
> >
> > if (( $# > 1 )) && [[ -t 0 && -t 1 ]] || ((list)); then
>
> IMHO, this is not equivalent to the first expression; it would
> something like be :
>
> if ( (( $# > 1 )) && [[ -t 0 && -t 1 ]] ) || ((list)); then
> or
> if ( (( $# > 1 )) && [[ -t 0 && -t 1 ]] ) || [[ -n ${list}
> ]]; then
>
> note the ( ... )
>
I tested that before posting and I think I'm correct. In lists of
command pipelines, || and && have the same precedence in that part of
the ksh grammar. So putting the test of $list to the end makes the flow
correct. Here's a test which shows that my un-parenthesized version is a
correct equivalent, and also how a naive rewrite would be wrong due to
the equal precedence of || and &&.
while read a b c; do
echo -n $a $b $c :
# intention: fully parenthesized
if [[ $a -eq 1 || ( $b -eq 1 && $c -eq 1 ) ]]
then echo -n " A=T"
else echo -n " A=F"
fi
# possible unparenth'd rewrite which is wrong
if ((a)) || ((b)) && ((c))
then echo -n " B=T"
else echo -n " B=F"
fi
# my rewrite (equivalent)
if ((b)) && ((c)) || ((a))
then echo -n " C=T"
else echo -n " C=F"
fi
# your rewrite
if ( ((b)) && ((c)) ) || ((a))
then echo -n " D=T"
else echo -n " D=F"
fi
echo
done <<++
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
++
I agree it's a bit tragic to see:
"The symbols && and || also have equal precedence."
in the shell man pages for lists (section Commands, discussing simple
commands, pipelines and lists) but that's the way it is.
_______________________________________________
ast-users mailing list
[email protected]
https://mailman.research.att.com/mailman/listinfo/ast-users