Last updated on February 24, 2021 by Dan Nanni
When you are writing a bash script, sometimes you may want to crunch numbers quickly inside the script. For example, you want to convert a unit of data you are working with, round a divided value to the nearest integer, increment a counter in simple loops, etc. Every programming language has built-in support for basic arithmetic operations against common data types. However, since bash is not a general-purpose programming language, but rather a command-line interpreter, it comes with limited support for arithmetic operations.
In this tutorial, I present tips on how to perform integer or floating point arithmetic operations in a bash shell script.
Variables in bash are not strongly-typed. By default all bash variables are character strings, unless specified with
declare. To support arithmetic operations on such string variables, bash treats variables as integers if dicated by execution context. To be more specific, if you are applying arithmetic/comparison operators to the variables that contain only digits, bash automatically treats the variables as integers. Such automatic string-to-integer conversion allows bash to evaluate integer arithmetic. However, bash does not support floating point calculation natively, and you will need to rely on external tools such as GNU bc for floating point operations.
While there are multiple ways to perform integer arithmetic in bash, it is recommended, for portability of your script, to use bash's built-in mechanism rather than relying on any external command. Bash's built-in support for integer arithmetic is called arithmetic evaluation. In a nutshell, if you want to perform integer arithmetic using arithmetic evaluation, all you have to do is to surround an arithmetic expression with double parentheses as follows. The format of an arithmetic expression contained in the parentheses is based on the C programming language.
(( arithmetic-expression ))
Check out the examples of how you can express integer arithmetic using arithmetic evalution in bash.
# Integer variables can be stored with or without quote a=100 b="3" (( sum = a + b )) # addition (( sub = a - b )) # subtraction (( mul = a * b )) # multiplication (( div = a / b )) # division (( mod = a % b )) # modulo (remainder) (( exp = a ** b )) # exponentiation echo "sum: $sum, sub: $sub, mul: $mul, div: $div, mod: $mod, exp: $exp"
As expected, you will see the following output.
sum: 103, sub: 97, mul: 300, div: 33, mod: 1, exp: 1000000
Note that since bash does not support floating point data type, division of two variables will always produce an integer result by truncation toward zero.
Using arithmetic evaluation, you can also increment or decrement integer variables in bash.
a=100 (( a++ )) echo "a = $a" (( a-= 10 )) echo "a = $a"
a = 101 a = 91
It's also possible to evaluate multiple arithmetic operations within a single expression.
(( form1 = a + b * 100, form2 = a * 100 + b * 2 ))
In arithmetic evaluation, if you are trying to use floating point numbers, you will see "syntax error: invalid arithmetic operator" error.
A slightly different built-in mechanism for integer arithmetic in bash is arithmetic expansion. In this case, the output of the arithmetic expression substitutes the expression itself and can be assigned to anther variable.
$(( arithmetic-expression ))
a=100 b="3" sum=$(( a + b )) sub=$(( a - b ))
Another way to perform integer arithmetic natively in bash is to use a built-in command called
let, which can evaluate a supplied arithmetic expression.
a=100 b="3" let sum=a+b # there shouldn't be any space before/after assignment let sub=a-b let mod=a%b let mod=a%b
You can also perform multiple arithmetic operations in a single
# Both statements are possible let 'tmp=a' 'a=b+1' 'b=tmp+1' let 'tmp=a, a=b+1, b=tmp+1'
You can also perform integer calculation in bash by using the
expr command. Unlike
let, which is bash's built-in command,
expr is an external command line utility that can evaluate an integer expression. Since it is part of GNU Coreutils, using
expr in your script does not affect the portability of the script.
a=100 b="3" # there must be spaces before/after the operator sum=`expr $a + $b` sub=`expr $a - $b` mul=`expr $a \* $b` div=`expr $a / $b` mod=`expr $a % $b`
The arithmetic operations supported by
expr are addition (+), subtraction (-), multiplication (*), division (/) and modulo (%). Note that multiplication operator must be escaped with '\' as '*' has a built-in meaning of all files in the current directory.
bcCommand (for Floating Point Arithmetic)
As clarified in the beginning, bash does not support floating point arithmetic natively. In case your bash script does require floating point math, one way to get around the bash's limitation is to invoke an external tool that can deal with floating point arithmetic. One such tool is GNU bc. Unless you are working with a minimal container environment, the
bc command should come pre-installed on all modern Linux distributions.
See the example below that runs floating point arithmetic using the
bc tool. You need to use
echo to pass floating point numbers to
a=12.5 b=5.8 # there must be spaces before/after the operator sum=`echo "$a + $b" | bc` mul=`echo "$a * $b" | bc` div=`echo "scale=2; $a / $b" | bc` echo "sum: $sum, mul: $mul, div: $div"
bc, you can adjust the precision of floating point numbers by changing a special variable called
scale. So for example, the output of the following floating point division will include two decimal digits after the decimal point.
div=`echo "scale=2; $a / $b" | bc`
The output of the example script looks like the following.
sum: 18.3, mul: 72.5, div: 2.15
bashshell scripting tutorials provided by Xmodulo.
Please note that this article is published by Xmodulo.com under a Creative Commons Attribution-ShareAlike 3.0 Unported License. If you would like to use the whole or any part of this article, you need to cite this web page at Xmodulo.com as the original source.