Performing Arithmetic in Bash Scripts

Summary:
Basic math using expr, let, (( )), and $(( )).


Bash scripts are powerful tools for automating tasks on Unix-like systems. Besides handling logic, conditions, and loops, sometimes your scripts need to perform arithmetic. Bash offers several ways to do basic math, each with its syntax and use-cases. In this article, we'll explore four common approaches to arithmetic in Bash: expr, let, (( )), and $(( )).


1. Using expr

expr is one of the oldest ways to perform integer arithmetic in shell scripts. Each operator and operand must be separated by spaces, and many operators (like *) need to be escaped.

Example:

#!/bin/bash

a=8
b=4

sum=$(expr $a + $b)
product=$(expr $a \* $b)

echo "Sum: $sum"
echo "Product: $product"

Notes:

  • Spaces are necessary: expr 5+3 won't work, but expr 5 + 3 will.
  • Multiplication (*) must be escaped: \*.
  • Only integer arithmetic is supported.
  • Outputs the result to stdout, so we usually use command substitution: $(...).

2. Using let

The let command allows simple arithmetic evaluation of shell variables.

Example:

#!/bin/bash

a=8
b=4

let sum=a+b
let product=a*b

echo "Sum: $sum"
echo "Product: $product"

Notes:

  • No need to use $ when referring to variables inside the let statement.
  • Handles arithmetic on variables directly.
  • Also supports increment (let a++) and decrement (let a--).

3. Using Arithmetic Expansion: $(( ))

Arithmetic expansion is the most common and modern way to do math in Bash. It evaluates the expression inside $(( )) and returns the result.

Example:

#!/bin/bash

a=8
b=4

sum=$((a + b))
product=$((a * b))

echo "Sum: $sum"
echo "Product: $product"

Notes:

  • No need for escapes or extensive quoting.
  • Supports variables and numeric constants.
  • Can be used for variable assignment or directly inside echo.

4. Using Arithmetic Evaluation: (( ))

The double parenthesis syntax allows evaluation of arithmetic expressions, similar to let.

Example:

#!/bin/bash

a=8
b=4

((sum = a + b))
((product = a * b))

echo "Sum: $sum"
echo "Product: $product"

You can also use it to increment or decrement variables concisely:

((a++))
((b--))

Notes:

  • Useful as a standalone command, especially in loops or conditional tests.
  • Variables inside do not require $.
  • Exit status of (( )) can be used for conditions (if (( a > b )); then ...).

Comparison Table

Method Syntax Supports Common Usage
expr expr $a + $b Integers Older scripts/compat.
let let a+=1 Integers Variable assignment
$(( )) sum=$((a + b)) Integers Modern, concise
(( )) ((a++)) Integers In-place calculations

Which Should I Use?

  • Preferred approach: $(( )) for most arithmetic needs—it's readable, concise, requires no escaping, and well supported in modern Bash.
  • Conditionals and Loops: (( )) is convenient for direct use in tests and increments.
  • Compatibility: Use expr if you need portability to very old shells.

Sample Script

Here's a sample script using all four methods:

#!/bin/bash

a=10
b=3

# expr
sum1=$(expr $a + $b)
echo "expr sum: $sum1"

# let
let sum2=a+b
echo "let sum: $sum2"

# $(( ))
sum3=$((a + b))
echo "\$(( )) sum: $sum3"

# (( ))
((sum4 = a + b))
echo "(( )) sum: $sum4"

Conclusion

Performing arithmetic in Bash can be done in several ways, but modern scripts almost always favor $(( )) and (( )) for their simplicity and power. Understanding all available methods, however, ensures your scripts are robust and maximally compatible.


Further Reading: