6.1. Arithmetic#

Bash can perform arithmetic on integers. Understanding the different ways to do arithmetic—and their limitations—is crucial for writing robust scripts.

6.1.1. Common Pitfalls#

6.1.1.1. ❌ Integer Division Gotcha#

# Bash only does INTEGER division
$ echo $((10 / 3))
3      # Not 3.33!

# For decimals, use bc or awk
$ echo "scale=2; 10/3" | bc
3.33

6.1.1.2. ❌ Variables Without $#

# Inside $((...)), DON'T use $ on variable names
$ a=5
$ echo $((a + 3))      # Correct
8
$ echo $(($a + 3))     # Also works, but unnecessary
8

# Outside, you DO need $
$ echo $a              # Need $
5

6.1.1.3. ❌ Division by Zero#

$ divisor=0
$ echo $((10 / $divisor))
bash: 10 / 0: division by zero (error)

# Guard against this:
$ if (( divisor != 0 )); then
>   result=$((10 / divisor))
$ fi

6.1.2. Real-World Examples#

6.1.2.1. Example 1: Calculate Total from User Input#

#!/bin/bash
echo "Enter price: "
read price
echo "Enter quantity: "
read qty

total=$((price * qty))
echo "Total: $total"

6.1.2.2. Example 2: Loop Counter#

#!/bin/bash
for ((i=1; i<=5; i++)); do
  echo "Iteration $i"
done

6.1.2.3. Example 3: Calculate Percentage#

#!/bin/bash
used=750
total=1000
percent=$((used * 100 / total))
echo "Disk usage: ${percent}%"

6.1.3. Shorthand Assignment Operators#

These modify a variable in place:

$ a=10
$ ((a += 5))      # a = a + 5 → 15
$ ((a -= 3))      # a = a - 3 → 12
$ ((a *= 2))      # a = a * 2 → 24
$ ((a /= 4))      # a = a / 4 → 6
$ ((a %= 4))      # a = a % 4 → 2
$ echo $a
2

6.1.3.1. Increment and Decrement: Pre vs Post#

# Pre-increment: increment first, then use value
$ a=5
$ echo $((++a))  # Increment a to 6, then evaluate
6
$ echo $a
6

# Post-increment: use value first, then increment
$ a=5
$ echo $((a++))  # Return 5, then increment a to 6
5
$ echo $a
6

# Same for decrement
$ a=5
$ echo $((--a))  # 4
$ echo $((a--))  # 3 (but a becomes 3)

6.1.4. The Operators#

Operator

Name

Example

Result

+

Addition

$((5 + 3))

8

-

Subtraction

$((5 - 3))

2

*

Multiplication

$((5 * 3))

15

/

Division (integer)

$((10 / 3))

3 (not 3.33)

%

Modulo (remainder)

$((10 % 3))

1

**

Exponentiation

$((2 ** 3))

8

++

Increment

$((a++))

Depends on position

--

Decrement

$((a--))

Depends on position

Using double parentheses for conditions:

# Returns 0 (true) or 1 (false)
$ if (( 5 > 3 )); then
>   echo "5 is greater"
$ fi
5 is greater

# Can use in expressions
$ (( 10 > 5 )) && echo "yes" || echo "no"
yes

Best for conditions, not value calculation.

6.1.4.1. Arithmetic Context: ((…))#

6.1.4.2. let: The Built-in#

A bash built-in for arithmetic assignment:

$ let a=5+3
$ echo $a
8

# Can be used to modify variables
$ a=10
$ let a=a+5
$ echo $a
15

# Shorthand operators work
$ let a+=10
$ echo $a
25

When to use:

  • For simple in-place modifications

  • Less common than $((...)) now

6.1.4.3. expr: The External Command#

The older approach (now mostly deprecated):

$ expr 5 + 3
8

# With variables, need $ and spaces around operators
$ a=10
$ expr $a + 3
13

# Assign to variable
$ result=$(expr $a + 3)
$ echo $result
13

Why avoid it:

  • External command (slower)

  • Requires spaces around operators

  • Harder to read

  • For backward compatibility only

The modern, preferred way to perform arithmetic:

# Basic syntax
$ result=$((5 + 3))
$ echo $result
8

# Works with variables
$ a=10
$ b=3
$ echo $((a + b))
13

# No dollar signs needed for variables
$ echo $((a * b))
30

# Spacing is flexible
$ echo $((a+b))    # Works
$ echo $(( a + b)) # Also works
13

Advantages:

  • Modern POSIX syntax

  • Works in all modern shells

  • Variables don’t need $ prefix

  • Supports many operators

  • Clean, readable syntax

6.1.4.4. Arithmetic Expansion: $((…))#

6.1.5. Four Ways to Do Arithmetic in Bash#

Bash provides multiple mechanisms for arithmetic, each with different syntax and capabilities: