Bash arithmetic operators
Bash evaluates integer math inside three constructs: arithmetic expansion
$(( expr )) which substitutes the result, the arithmetic command (( expr ))
which sets the exit status, and the let builtin. They share one operator set
modelled on the C language: arithmetic, bitwise, shifts, comparison, logical,
the ternary conditional and compound assignment. This page is a searchable,
offline reference that also shows each operator’s precedence so you know when
parentheses are required.
How it works
Inside an arithmetic context every token is interpreted numerically. Bare variable names expand to their values automatically, non-numeric strings become zero, and the whole expression yields an integer. Operators are applied in precedence order:
- Highest binding: post/pre increment, unary sign and
~/!, then**. - Then the multiplicative
* / %, additive+ -, and shifts<< >>. - Then relational
< <= > >=, equality== !=. - Then the bitwise trio in order
&,^,|— note these bind looser than the comparisons, a common source of bugs. - Then logical
&&and||, the ternary?:, and finally assignment and the comma operator.
Comparison and logical operators return 1 for true and 0 for false, which is
why (( x > 0 )) works as a condition: a non-zero result is a success exit
status.
Tips and examples
Use the arithmetic command directly as a loop condition:
for (( i = 0; i < 5; i++ )); do
echo "$i squared is $(( i ** 2 ))"
done
Compound assignment keeps counters terse:
total=0
(( total += 25 )) # total is now 25
(( total <<= 1 )) # bit-shift left → 50
The ternary operator picks a value inline without an if:
max=$(( a > b ? a : b ))
Remember everything is integer math: $(( 7 / 2 )) is 3, not 3.5. For
fractional results, reach for bc -l or awk instead.