wardva
wardva

Reputation: 624

If statement with arithmetic comparison behaviour in bash

I'm learning bash and I noticed something weird I can't (yet) explain. At school I learned that an if statement evaluates 0 as true and 1 as false, so it can be used with the status code from an other command. Now is my question: Why does this happen:

echo $((5>2)) #prints 1
echo $((5<2)) #prints 0
if ((5>2)) ; then echo "yes" ; else echo "no" ; fi #prints yes
if ((5<2)) ; then echo "yes" ; else echo "no" ; fi #prints no

This doesn't seem logical. How does bash know i'm using an arithmetic expression and not another command?

Upvotes: 5

Views: 676

Answers (3)

chepner
chepner

Reputation: 531275

$((...)) is an arithmetic expression; it expands to the value of the expression inside the parentheses. Since it is not a command, it does not have an exit status or return value of its own. A boolean expression evaluates to 1 if it is true, 0 if it is false.

((...)), on the other hand, is an arithmetic statement. It is a command in its own right, which works be evaluating its body as an arithmetic expression, then looking at the resulting value. If the value is true, the command succeeds and has an exit status of 0. If the value is false, the command fails, and has an exit status of 1.

It's a good idea when learning bash to stop thinking of the conditions in if statements, while loops, etc. as being true or false, but rather if the commands succeed or fail. After all, shell languages are not designed for data processing; they are a glue language for running other programs.

Upvotes: 3

olovb
olovb

Reputation: 2254

From the bash manual:

((expression))

The expression is evaluated according to the rules described below under ARITHMETIC EVALUATION. If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. (My emphasis.)

So essentially in a boolean context ((expression)) gives the inverse of what $((expression)) would give.

Upvotes: 2

Tom Fenech
Tom Fenech

Reputation: 74645

You're confusing the output of the command substitution and the return value of the arithmetic context.

The output of the command substitution is 1 for true and 0 for false.

The return value of (( )) is 0 (success) if the result is true (i.e. non-zero) and 1 if it is false.

if looks at the return value, not the output of the command.

Upvotes: 7

Related Questions