bug-bash
[Top][All Lists]
Advanced

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

Re: Conditions with logical operators and nested groups execute "if" and


From: Greg Wooledge
Subject: Re: Conditions with logical operators and nested groups execute "if" and "else"
Date: Thu, 31 May 2018 08:30:44 -0400
User-agent: NeoMutt/20170113 (1.7.2)

On Wed, May 30, 2018 at 05:02:58PM -0700, L A Walsh wrote:
> Greg Wooledge wrote:
> > On Mon, May 21, 2018 at 04:17:18PM -0500, Uriel wrote:
> > > [[ EXPRESSION ]]; && { TRUE CONDITION; } || { ALTERNATIVE RESULT; }
> > https://mywiki.wooledge.org/BashPitfalls#pf22
> pf22 is wrong.

It's not wrong.

> It says:
> 
> i=0
> true && ((i++)) || ((i--))  # WRONG!
> echo "$i"                   # Prints 0

Yes, it says that.

> You should change the above to "never use post- increment or decrement
> if pre- increment or decrement will do.
> 
> You meant to increment 'i' so the expression would have been ((1))
> (which is true), so:
>   > true && ((++i)) || ((i--))
>   > echo $i
>   1
> evaluates to 1 as you expected.

You need to read the rest of the Pitfall:

==========================================================================
Another clever person thinks that we can fix it by using the pre-increment
operator, since the exit status from ++i (with i initially 0) is true:

 i=0
 true && (( ++i )) || (( --i ))  # STILL WRONG!
 echo "$i"                       # Prints 1 by dumb luck

But that's missing the point of the example. It just happens to work by
coincidence, and you cannot rely on x && y || z if y has any chance of
failure! (This example still fails if we initialize i to -1 instead of 0.)
==========================================================================

The entire pointg of Pitfall 22 is that the following two chunks of
code  *** ARE NOT EQUIVALENT ***


Chunk 1:
a && b || c

Chunk 2:
if a; then b; else c; fi


People think they can use chunk 1 as some sort of "shorthand" for chunk 2,
but they are NOT THE SAME.

Chunk 1 is WRONG if the objective is to get the same result as chunk 2.

Changing the i++ to ++i is COMPLETELY MISSING THE POINT.

ARITHMETIC WAS JUST THE SIMPLEST POSSIBLE EXAMPLE TO DEMONSTRATE THE ISSUE.

Changing "b" to "q" and then saying "a && q || c works! so you should have
used q instead of b all along!" IS NOT A USEFUL CRITICISM.

Sadly, you were not the first person to try to "correct" the pitfall by
changing the arithmetic operation to one that just happens to fail to
demonstrate the issue by dumb luck.  This is why the Pitfalls page and
the FAQ pages have broken code and explanations of why the broken code
is broken.

If I DON'T show the broken code, SOMEONE ELSE WILL INEVITABLY COME ALONG
AND ADD THE BROKEN CODE, THINKING THAT THEY ARE CLEVER.

So I have to continually monitor the RecentChanges page, look for the
"clever" submissions, and rewrite them as examples of Bash Gone Wrong.

And apparently even THAT isn't enough, because people don't even read
the explanation of why their "clever" solution is wrong, but instead
just go and spew the "clever" solution to a mailing list... and then
someone else will see it and copy it... and the cycle REPEATS FOREVER.



reply via email to

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