Reputation: 371
I'm doing simple calculations in bash and I noticed that bash calculations using expr
return 1 if the result of the calculation is zero.
user@machine:~$ expr 42 - 40 ; echo $?
2
0
user@machine:~$ expr 42 - 84 ; echo $?
-42
0
user@machine:~$ expr 42 - 42 ; echo $?
0
1
Why does bash do this? Isn't a return value of 1 an indication that the program failed? Doesn't this behaviour violate good practice?
I'm doing some calculations inside a script run with set -e
.
What is the best way to account for the return value of 1?
I could do
expr $var1 - $var2 || true
but this would also ignore other exit codes than 1.
Upvotes: 0
Views: 409
Reputation: 531275
This is just the mapping of integers (as Boolean values, 0=False, 1=True) to shell exit codes (0=Success, >0=Failure). Note that "failure" does not necessarily mean "program experienced an error and/or crashed". Other programs do similar things:
* `grep` exits with 0 if a match is made, 1 if no match is made.
* `test` exits 0 if its condition is true, 1 if its condition is false.
In C, you can use the result of an arithmetic expression directly as the condition of an if
or while
statement.
In shell, such statements test the exit code of a command, treating success as analogous to true and failure as analogous to false. In this sense, expr ...
is short for test ... -ne 0
.
In a typical language, you write something like
# Python
n = 10
while n - 3: # short for n > 3
...
expr
performs arithmetic, so it makes sense for the exit status to allow the same.
n=10
while expr "$n" - 3; do
...
done
Note that you can still detect actual errors, as opposed to Boolean falseness, by checking if the exit status of expr
is greater than 1.
n=10
while true; do # "Infinite" loop
expr "$n" - 3
case $? of
1) break ;;
2) echo "Error with expr" >&2; break ;;
esac
...
done
Upvotes: 1