Thuta Learning
IntermediateDevOps & Toolsbeginner

Arithmetic and Numeric Comparisons

What you'll walk away with

  • Explain the core ideas behind Arithmetic and Numeric Comparisons
  • Run the sample code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

Bash treats every variable as a string by default, which is why arithmetic needs its own dedicated contexts rather than working automatically the way it does in languages with native number types. $(( expression )) evaluates an arithmetic expression and substitutes the resulting number, so you can capture it in a variable or print it directly, as with $((a + b)) or $((a ** 2)) for exponentiation. (( expression )) does the same underlying evaluation but discards the number and instead sets the command's exit status based on whether the result is nonzero (true) or zero (false), which is exactly what if and while need — it is also how compound assignment shortcuts like ((a += 5)) work, mutating a variable in place. The older let command, as in let "b *= 2", predates this dedicated form of (( )) and still works, but is rarely used in new scripts because the (( )) syntax is clearer and more consistent. The trickiest part for beginners is that [[ ]] supports two entirely different kinds of comparison operator depending on what you're comparing: -eq, -ne, -lt, -le, -gt, -ge for numbers, and ==, != for strings — and bash will never warn you if you pick the wrong family. It simply performs whichever comparison you asked for, numeric or lexicographic, even when the result looks like nonsense for what you actually meant.

Connect it to a real scenario

Picture a script that reads a numeric threshold from a config file as a string and compares it against a count of failed jobs to decide whether to send an alert — this lesson's code demonstrates exactly how easy it is to get this wrong. With x="10" and y="9", the numeric comparison [[ "$x" -gt "$y" ]] correctly reports that x is greater, because -gt forces bash to interpret both operands as integers before comparing. But [[ "$x" > "$y" ]] using the string operator > compares them character by character instead: it looks at the first character of each, '1' versus '9', and since '1' sorts before '9' lexicographically, it concludes x is NOT greater — the opposite of the numeric truth. This is precisely the kind of bug that breaks alerting logic silently: a threshold of 9 could look 'greater than' a count of 10 with no error message at all, because both are perfectly valid strings as far as bash is concerned. The lesson's code sidesteps this entirely with (( a > b )) for arithmetic evaluated inside an if, and -gt inside [[ ]] whenever numbers are being compared — the discipline is to always ask yourself whether you're comparing quantities or comparing text, and pick the matching operator family every time, since bash itself won't catch the mistake for you.

Try the working example

bash
#!/bin/bash
a=10
b=3

echo "Sum: $((a + b))"
echo "Quotient: $((a / b))"
echo "Remainder: $((a % b))"
echo "Power: $((a ** 2))"

((a += 5))
echo "a after += 5: $a"

let "b *= 2"
echo "b after *= 2: $b"

if (( a > b )); then
  echo "a is numerically greater than b"
fi

x="10"
y="9"
if [[ "$x" -gt "$y" ]]; then
  echo "Numeric compare: x is greater than y"
fi

if [[ "$x" > "$y" ]]; then
  echo "String compare: x is greater than y"
else
  echo "String compare: x is NOT greater than y"
fi
You should see
Running this script prints:

Sum: 13
Quotient: 3
Remainder: 1
Power: 100
a after += 5: 15
b after *= 2: 6
a is numerically greater than b
Numeric compare: x is greater than y
String compare: x is NOT greater than y

5-minute try-it

Write a small script that stores two numbers as strings, e.g. "20" and "9", and prints whether the first is greater than the second using both a numeric comparison and a string comparison, so you can see the results disagree.

One important caution

Using == inside [[ ]] to compare two numbers, which works as a string comparison and gives wrong answers for multi-digit numbers like "9" vs "10"

Using -eq, -lt, etc. on a variable that isn't a valid integer, which causes bash to throw an 'integer expression expected' error at runtime

GNU Bash Manual: Shell ArithmeticBash / Shell Scripting

Easy traps

  • Using == inside [[ ]] to compare two numbers, which works as a string comparison and gives wrong answers for multi-digit numbers like "9" vs "10"
  • Using -eq, -lt, etc. on a variable that isn't a valid integer, which causes bash to throw an 'integer expression expected' error at runtime
  • Validate sample code in a local or test environment before applying it to a production system.

Exercise

Write a small script that stores two numbers as strings, e.g. "20" and "9", and prints whether the first is greater than the second using both a numeric comparison and a string comparison, so you can see the results disagree.

You'll know it worked when: Running this script prints: Sum: 13 Quotient: 3 Remainder: 1 Power: 100 a after += 5: 15 b after *= 2: 6 a is numerically greater than b Numeric compare: x is greater than y String compare: x is NOT greater than y

Arithmetic and Numeric Comparisons | Thuta Learning