Arithmetic operations in the Bash are different to most other programming languages. As seen in (Part 3)[/tutorials/bash-scripting-variables] of this tutorial, bash variables are untyped, which can bring certain issues in treating them as numbers.
There are multiple ways to perform arithmetic operations in the Bash. After looking at the builtin let
command in the last part, we are going to focus on the arithmetic evaluation mode of the Bash.
Most shells, including the Bash, can only use Integers for calculations. Decimal numbers are not supported without using other cli applications, like
bc
.
#!/usr/bin/env bash
a=20
b=22
# Prints 20 + 22
echo "$a + $b"
# Prints 42
echo $((a + b))
In order to sum up our two variables, we need to switch to the arithmetic evaluation mode with two parenthesis ((a + b))
. We don't need to use the dollar sign for our variables in this case (you can though), because in this mode only integers or variables can be used.
$ echo $((4 + 2))
6
$ echo $(("text" + 2))
bash: bad math expression: illegal character: "
$ echo $((text + 2))
2
$ a=1
$ echo $((a + 2))
3
Incrementing and decrementing a variable in the Bash by one is the same as in most programming languages.
$ a=1
$ ((a++))
$ echo "$a"
2
$ echo $((a++)) # Caution!
2
$ echo "$a"
3
When using the "++" operator, the value of the variable is first returned and then increased.
$ a=1
$ echo $((a++))
1
$ echo $((++a))
3
$ echo $((a--))
3
$ echo "$a"
2
$ echo $((--a))
1
In computing, the modulo operation gets the remaining integer after a division of one of each other. This is quite useful for multiple purposes, for example to work out if an integer is odd or even.
$ echo $((10 % 4))
2
$ echo $((11 % 4))
3
$ echo $((12 % 4))
0
$ echo $((9 % 2))
1
bc
As the Bash is not supporting floating point arithmetics we need to use another cli program for it, with bc
being the most common on Linux distributions.
Some shells, like ksh93 or zsh, have some support for decimal arithmetics, when you use a decimal number as input, e.g.
echo $((11.0 / 3))
.
$ echo $((10 / 3))
3
$ echo $((11 / 3))
3
$ echo "11 / 3" | bc
3
$ echo "11 / 3" | bc -l
3.66666666666666666666
$ echo "11.0 / 3" | bc
3.66666666666666666666
We pipe the expression to bc in order to get the result. if you use integers as inputs though, bc, behaves like the Bash and crops the result.
Storing the result in a variable is done with the command substitution mode.
$ result=$(echo "11 / 3" | bc -l)
$ echo "$result"
3.66666666666666666666
The expr
command from the GNU coreutils can be used for mathematical calculations and comparisons.
The exit code of
expr
is 1 if the result is zero or null! Also beware that many operators need to be escaped or quoted.
$ expr 20 + 22
42
$ a=$(expr 20+22) # Using command substitution to store the result in an variable.
$ echo "$a"
42
# Make sure to escape the asterisk
$ expr $a \* 3
As seen in the last part, you can also use let
for assigning variables with an expression.
$ a=2
$ let b=$a+40
$ echo "$b"
42