Re: inconsistent exit status of ((count++))

2010-07-30 Thread Stefano Lattarini
At Friday 30 July 2010, Greg Wooledge wrote:
> On Fri, Jul 30, 2010 at 09:49:22PM +0200, Stefano Lattarini wrote:
> > But then, maybe an exit status of `2' instead of `1' in case of
> > errors in ((...)) would be helpful -- currently the exit status
> > is still `1'
> > 
> > also if a real error is present:
> >   $ ((1+)); echo \$?=$?
> >   bash: ((: 1+: syntax error: operand expected (error token is
> >   "+") $?=1
> 
> Most syntax errors cause the shell to abort right then and there,
> when in non-interactive mode.  Syntax errors inside an arithmetic
> context don't, which is already weird.  If I were going to ask for
> a change,
Well, I wasn't really advocating a change here, since I've never had
problems with the current behaviour; I was just pointing out that
it is suboptimal.

> it would be to make them crash the script instead of
> letting bash continue.
This makes sense; now I think that, if there's going to be a change, 
it should be on the lines proposed by you.

Regards,
  Stefano



Re: inconsistent exit status of ((count++))

2010-07-30 Thread Greg Wooledge
On Fri, Jul 30, 2010 at 09:49:22PM +0200, Stefano Lattarini wrote:
> But then, maybe an exit status of `2' instead of `1' in case of errors
> in ((...)) would be helpful -- currently the exit status is still `1'
> also if a real error is present:
> 
>   $ ((1+)); echo \$?=$?
>   bash: ((: 1+: syntax error: operand expected (error token is "+")
>   $?=1

Most syntax errors cause the shell to abort right then and there, when in
non-interactive mode.  Syntax errors inside an arithmetic context don't,
which is already weird.  If I were going to ask for a change, it would
be to make them crash the script instead of letting bash continue.



Re: inconsistent exit status of ((count++))

2010-07-30 Thread Greg Wooledge
On Fri, Jul 30, 2010 at 07:33:00PM +0100, Andrew Benton wrote:
> On 30/07/10 19:55, Stefano Lattarini wrote:
> >I don't think it's a bug, it's just an effect of:
> >   1. `((EXPR))' returning a non-zero exit status iff EXPR evaluates
> >  to zero, and

> That makes no sense to me. Why would evaluating an expression have a 
> non-zero exit status if there was no error?

The ((...)) command is used like this:

  if ((a < b)); then
stuff
  fi

So it returns an exit status -- true or false -- depending on whether the
arithmetic expression inside it is true or false.

The syntax and semantics of the arithmetic expression are almost identical
to what's used in C.  Any expression in there has a value.  Equations or
inequalities are special cases, but just like in C, plain ol' integers
have "true" and "false" values as well:

imadev:~$ ((42)); echo $?
0
imadev:~$ ((0)); echo $?
1

There is no real concept of an "error" in an arithmetic context.  The
exit status of an arithmetic command (either ((...)) or let) is simply
determined by the value of the expression inside it.

imadev:~$ let a=5/2; echo $?
0
imadev:~$ let a=0/2; echo $?
1

In fact, the only way you CAN generate an error in an arithmetic context
is to divide by zero:

imadev:~$ let a=2/0; echo $?
bash: let: a=2/0: division by 0 (error token is "0")
1

But that is such a rare case, and so completely preventable, that there's
just no provision to distinguish it from the case where an expression
evaluates to zero.



Re: inconsistent exit status of ((count++))

2010-07-30 Thread Stefano Lattarini
At Friday 30 July 2010, Andrew Benton wrote:
> On 30/07/10 19:55, Stefano Lattarini wrote:
> > At Thursday 29 July 2010, Andrew Benton wrote:
> >> andy:~$ count=0
> >> andy:~$ ((count++))
> >> andy:~$ echo $?
> >> 1
> >> andy:~$ ((count++))
> >> andy:~$ echo $?
> >> 0
> > 
> > I don't think it's a bug, it's just an effect of:
> >1. `((EXPR))' returning a non-zero exit status iff EXPR
> >evaluates to zero, and
BTW, this behaviour is documented here, in the entry `((...))':

 
> That makes no sense to me. Why would evaluating an expression have
> a non-zero exit status if there was no error?
It can be very useful for use in conditional or looping constructs, e.g.:

  if ((verbosity > 1)); then
echo "blah blah..."
  fi

Also, non-zero exit status does not necessary indicate a true error in
the Unix world (the `grep' utility is a noteworthy and outstanding
example).

> That makes the exit status no use at all for evaluating whether an
> error has occurred.
> How can I check for errors if I can't rely on the exit status? How
> can that not be a bug?
>
It's somewhat of a trade-off; and I hope that my explanation makes it
clear that it's a good tradeoff.

But then, maybe an exit status of `2' instead of `1' in case of errors
in ((...)) would be helpful -- currently the exit status is still `1'
also if a real error is present:

  $ ((1+)); echo \$?=$?
  bash: ((: 1+: syntax error: operand expected (error token is "+")
  $?=1

Regards,
  Stefano



Re: inconsistent exit status of ((count++))

2010-07-30 Thread Andrew Benton

On 30/07/10 19:55, Stefano Lattarini wrote:

At Thursday 29 July 2010, Andrew Benton wrote:


andy:~$ count=0
andy:~$ ((count++))
andy:~$ echo $?
1
andy:~$ ((count++))
andy:~$ echo $?
0

I don't think it's a bug, it's just an effect of:
   1. `((EXPR))' returning a non-zero exit status iff EXPR evaluates
  to zero, and
That makes no sense to me. Why would evaluating an expression have a 
non-zero exit status if there was no error? That makes the exit status 
no use at all for evaluating whether an error has occurred. How can I 
check for errors if I can't rely on the exit status? How can that not be 
a bug?


Andy



Re: inconsistent exit status of ((count++))

2010-07-30 Thread Stefano Lattarini
At Thursday 29 July 2010, Andrew Benton wrote:
> 
> andy:~$ count=0
> andy:~$ ((count++))
> andy:~$ echo $?
> 1
> andy:~$ ((count++))
> andy:~$ echo $?
> 0
I don't think it's a bug, it's just an effect of:
  1. `((EXPR))' returning a non-zero exit status iff EXPR evaluates
 to zero, and
  2. `var++' being a *post-increment* (i.e. the increment of `var'
 takes place after its previous value has been substituted in
 the expression).

You can verify this with:
  $ i=0
  $ echo $((i++))
  0
  $ echo $i
  1
  $ echo $((++i))
  2
  $ echo $i
  2

> 
> Fix:
> 
> This isn't a fix but I can work around this bug if I use
> ((++count))
Yes, because here `count' is incremented before its value is 
substituted into the expression.

> 
> andy:~$ count=0
> andy:~$ ((++count))
> andy:~$ echo $?
> 0
> andy:~$

HTH,
   Stefano



inconsistent exit status of ((count++))

2010-07-30 Thread Andrew Benton

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' 
-DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' 
-DSHELL -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib   -g -O2
uname output: Linux eccles 2.6.35-rc6 #1 SMP Fri Jul 23 11:52:29 BST 
2010 x86_64 x86_64 x86_64 GNU/Linux

Machine Type: x86_64-unknown-linux-gnu

Bash Version: 4.1
Patch Level: 2
Release Status: release

Description:
[Detailed description of the problem, suggestion, or complaint.]

If I use set -e to make my scripts exit on error, the scripts fail if I 
use something like:


count=0
((count++))

Repeat-By:

andy:~$ count=0
andy:~$ ((count++))
andy:~$ echo $?
1
andy:~$ ((count++))
andy:~$ echo $?
0

Fix:

This isn't a fix but I can work around this bug if I use ((++count))

andy:~$ count=0
andy:~$ ((++count))
andy:~$ echo $?
0
andy:~$