Bash error: division by 0

Bash aborts arithmetic with "division by 0" when the divisor evaluates to 0, including when an unset variable defaults to 0.

Error String

bash: division by 0 (error token is "0")

Tldr

Arithmetic divisions in `(( ))` or `$(( ))` abort when the divisor is 0. Empty/unset variables count as 0, so check before dividing.

Cause

Common triggers: a counter that wasn't initialized, a divisor read from input without validation, or a calculation that depends on a configuration value that defaulted to 0.

Repro

total=100
count=
echo $(( total / count ))   # division by 0

Fix

total=100
count=${count:-1}
if (( count > 0 )); then
  echo $(( total / count ))
else
  echo "count is zero"
fi

Explanation

Guarding with `(( divisor > 0 ))` is the cleanest way to keep the script running. For percentages, use `(( total ? part * 100 / total : 0 ))` as a one-liner.

Faq

Q

Why is an unset variable a division by zero rather than a syntax error?

A

Bash arithmetic substitutes 0 for unset or empty names, so `$(( total / missing ))` becomes `total / 0`.

Q

Does set -u catch this?

A

Only for genuinely unset names. A variable assigned an empty string passes `set -u` and still evaluates to 0.

Deep Dive

Heading

Empty and non-numeric values become zero

Body

Inside `$(( ))` an unset or empty variable evaluates to 0, so a divisor that was never assigned turns a normal calculation into a division by zero. The same happens when a value came back from a command with trailing whitespace or an error message, because Bash arithmetic parses what it can and treats the rest as 0. Validate before dividing: `[[ $n =~ ^-?[0-9]+$ ]]` rejects anything that is not an integer, and `(( denom != 0 )) || { echo "no data" >&2; exit 1; }` gives the caller a real message instead of a shell error.

Heading

Percentages, averages and integer-only arithmetic

Body

Most real occurrences are averages over an empty set — dividing a total by a count that is zero because the input file was empty. Guard the count first and report "no samples" rather than computing anything. Remember also that Bash arithmetic is integer-only and truncates towards zero, so `(( 1/2 ))` is 0. For fractional results use `awk "BEGIN{print $a/$b}"` or `bc -l`, and guard the divisor there as well — awk prints `inf` instead of failing, which silently corrupts a report.

Checklist

Echo the divisor immediately before the arithmetic to see whether it is empty.

Reject non-numeric input with a regex test before doing any arithmetic.

Guard the zero case explicitly and emit a human-readable message.

Use awk or bc when you need fractional results, and guard the divisor there too.