user11703419
user11703419

Reputation:

Could you explain the syntax of math in a bash shell?

for i in {1..99}
do
  if ([ $((i % 2)) -eq 1 ])
  then
      echo $i
  fi
done

I'm learning bash, and I'm trying to better understand line 3. Why does $((i % 2)) have to be double wrapped in parenthesis, and why can't I put the $ symbole inside next to the i like:

([ (($i % 2)) -eq 1 ])

or

([ ($(i % 2)) -eq 1 ])

?

Upvotes: 5

Views: 3094

Answers (4)

wasif
wasif

Reputation: 15478

You can also use expr:

for i in {1..99}
do
  num=`expr i % 2`
  if (( num == 1 ))
  then
      echo $i
  fi
done

Upvotes: -1

Paul Hodges
Paul Hodges

Reputation: 15273

Since you specify bash, simplest is

for i in {1..99}
do  if ((i % 2)) 
    then echo $i
    fi
done

the ((i % 2)) will return i mod 2, which will always be zero or one. This particular construct behaves like a C-style boolean, so zero is false and anything else is true (the opposite behavior from [[ ... ]] which uses return code of zero to mean true/ok).

Upvotes: 0

Barmar
Barmar

Reputation: 780899

$(( expression )) is the syntax for evaluating an arithmetic expression, and replacing this syntax with the result of that expression. It's documented in the Bash Manual here;

The syntax of arithmetic expressions is described here. Putting $ before variable names is optional, so you can also write it as $(($i % 2)).

You have to wrap it in two parentheses because $(...) already has a meaning, it's used for command substitution: $(some command) executes some command and is then replaced with the output of the command.

You don't need parentheses around [ ... ]. The normal way to write your if statement would be

if [ $((i % 2)) -eq 1 ]

You can also write it as

if (( i % 2 == 1 ))

(( expression )) evaluatees the arithmetic expression, and then sets its exit status depending on whether the result is zero or non-zero.

Upvotes: 6

chepner
chepner

Reputation: 531075

Everything inside $((...)) is treated as an arithmetic expression. You can use parameter expansion inside an arithmetic expression, but a bare string is interpreted as a variable whose (integer) value is used. You can write

if [ $(( i % 2 )) -eq 1 ]

to check if i is odd. You can also check for equality inside the expression, as $(( x == y )) evaluates to 1 if x == y and 0 otherwise, but you would still have to compare that value to something.

In bash, you can use the arithmetic command, which has an exit status of 0 if the resulting value is non-zero, and 1 otherwise. This lets you write

if (( i % 2 == 1 )); then

Upvotes: 4

Related Questions