Discussion:
Is it reasonable to let zero numeric value results in non zero exit status?
Peng Yu
2018-10-21 21:18:31 UTC
Hi,

I see the following.

((x=0))
\$ echo \$?
1

I am not sure whether it is a good idea to return non zero exit status
when a numeric variable is zero, as this can cause problems when `set
-e` is used. Is there is a strong justification why this behavior is
reasonable?
--
Regards,
Peng
Eduardo A. Bustamante López
2018-10-21 21:33:16 UTC
On Sun, Oct 21, 2018 at 04:18:31PM -0500, Peng Yu wrote:
(...)
Post by Peng Yu
I am not sure whether it is a good idea to return non zero exit status
when a numeric variable is zero, as this can cause problems when `set
-e` is used. Is there is a strong justification why this behavior is
reasonable?
I understand what you're saying. I do have to ask though, how else would these examples work?

if ((a > b)); then
...
fi

while ((i--)); do
...
done

((x)) && echo hi

What rule would you use to know when to discard the return code?
Peng Yu
2018-10-22 02:30:08 UTC
I think that there is a mix of two purposes 1) just using the
numerical values, 2) conditional testing. They should not be mixed up.

For the case of ((a > b)), it is obviously a testing. Then it makes
sense to return 1.

But for ((i--)) or ((x)), it is only the numerical values that matter.

In the context of while ((i--)) and ((x)) && echo hi, they can be
written as while ((i--==0)) and ((x==0)) && echo hi to make elimintate
the ambiguity.
Post by Eduardo A. Bustamante López
(...)
Post by Peng Yu
I am not sure whether it is a good idea to return non zero exit status
when a numeric variable is zero, as this can cause problems when `set
-e` is used. Is there is a strong justification why this behavior is
reasonable?
I understand what you're saying. I do have to ask though, how else would
these examples work?
if ((a > b)); then
...
fi
while ((i--)); do
...
done
((x)) && echo hi
What rule would you use to know when to discard the return code?
--
Regards,
Peng
Pierre Gaston
2018-10-22 05:55:13 UTC
Post by Peng Yu
I think that there is a mix of two purposes 1) just using the
numerical values, 2) conditional testing. They should not be mixed up.
For the case of ((a > b)), it is obviously a testing. Then it makes
sense to return 1.
But for ((i--)) or ((x)), it is only the numerical values that matter.
In the context of while ((i--)) and ((x)) && echo hi, they can be
written as while ((i--==0)) and ((x==0)) && echo hi to make elimintate
the ambiguity.
I'm not sure if having a special case for this is a good idea.
It follows the C syntax and like in C the assignment has the value of the
of the variable after the assignment.
For what it's worth some think that it is not a good idea and error prone
e.g. python doesn't allow this.

Moreover, other assignments in bash can exit with non 0 eg:
x=\$(false);echo \$?

I personally prefer using: x=\$(( )) rather than ((x=)), I find it more
natural and it doesn't exit with 1.
Peng Yu
2018-10-22 13:16:25 UTC
That is a possible walkaround. But one drawback is x=\$((x+1)) is
slower than ((x=x+1))

See the following example.

==> main1.sh <==
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:

x=0
for((i=0;i<10000;++i))
do
x=\$((x+1))
x=\$((x+1))
x=\$((x+1))
x=\$((x+1))
x=\$((x+1))
x=\$((x+1))
x=\$((x+1))
x=\$((x+1))
x=\$((x+1))
x=\$((x+1))
done

==> main2.sh <==
#!/usr/bin/env bash
# vim: set noexpandtab tabstop=2:

x=0
for((i=0;i<10000;++i))
do
((x=x+1))
((x=x+1))
((x=x+1))
((x=x+1))
((x=x+1))
((x=x+1))
((x=x+1))
((x=x+1))
((x=x+1))
((x=x+1))
done
\$ time ./main1.sh

real 0m0.473s
user 0m0.453s
sys 0m0.012s
\$ time ./main2.sh

real 0m0.425s
user 0m0.411s
sys 0m0.007s
Post by Pierre Gaston
I personally prefer using: x=\$(( )) rather than ((x=)), I find it more
natural and it doesn't exit with 1.
--
Regards,
Peng
Greg Wooledge
2018-10-22 13:29:40 UTC