Introduction
Math and arithmetic operations are essential in Bash scripting. Various automation tasks require basic arithmetic operations, such as converting the CPU temperature to Fahrenheit. Implementing math operations in Bash is simple and very easy to learn.
This guide teaches you how to do basic math in Bash in various ways.
Prerequisites
- Access to the command line/terminal.
- A text editor to code examples, such as nano or Vi/Vim.
- Basic knowledge of Bash scripting.
Why Do You Need Math in Bash Scripting?
Although math is not the primary purpose of Bash scripting, knowing how to do essential calculations is helpful for various use cases.
Common use cases include:
- Adding/subtracting/multiplying/dividing numbers.
- Rounding numbers.
- Incrementing and decrementing numbers.
- Converting units.
- Floating-point calculations.
- Finding percentages.
- Working with different number bases (binary, octal, or hexadecimal).
Depending on the automation task, basic math and arithmetic in Bash scripting help perform a quick calculation, yielding immediate results in the desired format.
Bash Math Commands and Methods
Some Linux commands allow performing basic and advanced calculations immediately. This section shows basic math examples with each method.
Arithmetic Expansion
The preferable way to do math in Bash is to use shell arithmetic expansion. The built-in capability evaluates math expressions and returns the result. The syntax for arithmetic expansions is:
$((expression))
The syntax consists of:
- Compound notation
(())
which evaluates the expression. - The variable operator
$
to store the result.
Note: The square bracket notation ( $[expression]
) also evaluates an arithmetic expression, and should be avoided since it is deprecated.
For example, add two numbers and echo the result:
echo $((2+3))
The arithmetic expansion notation is the preferred method when working with Bash scripts. The notation is often seen together with if
statements and for loops in Bash.
awk Command
The awk command acts as a selector for pattern expressions. For example, to perform addition using the awk
command, use the following example statement:
awk 'BEGIN { x = 2; y = 3; print "x + y = "(x+y) }'
For variables x = 2
and y = 3
, the output prints x + y = 5
to the console.
bc Command
The bc
command (short for basic calculator) is a command-line utility that renders the bc language. The program runs as an interactive program or takes standard input to perform arbitrary precision arithmetic.
Pipe an equation from standard input into the command to fetch results. For example:
echo "2+3" | bc
The output prints the calculation result.
dc Command
The dc
command (short for desk calculator) is a calculator utility that supports reverse Polish notation. The program takes standard input and supports unlimited precision arithmetic.
Pipe a standard input equation into the command to fetch the result. For example:
echo "2 3 + p" | dc
The p
in the equation sends the print signal to the dc
command.
declare Command
The Bash declare command allows integer calculations. To use declare
for calculations, add the -i
option. For example:
declare -i x=2 y=3 z=x+y
Echo each variable to see the results:
echo $x + $y = $z
The output prints each variable to the console.
expr Command
The expr
command is a legacy command line utility for evaluating integer arithmetic. An example expr
command looks like the following:
expr 2 + 3
Separate numbers and the operation sign with spaces and run the command to see the calculation result.
factor Command
The factor
command is a command-line utility that prints the factors for any positive integer, and the result factorizes into prime numbers.
For example, to print the factors of the number 100, run:
factor 100
The output prints the factored number.
let Command
The Bash let command performs various arithmetic, bitwise and logical operations. The built-in command works only with integers. The following example demonstrates the let
command syntax:
let x=2+3 | echo $x
The output prints the results.
test Command
The test
command in Linux evaluates conditional expressions and often pairs with the Bash if statement. There are two variations for the test syntax:
test 2 -gt 3; echo $?
Or alternatively:
[ 2 -gt 3 ]; echo $?
The test
command evaluates whether two is greater than (-gt
) three. If the expression is true, the output is zero (0
), or one (1
) if false.
Bash Arithmetic Operators
Bash offers a wide range of arithmetic operators for various calculations and evaluations. The operators work with the let
, declare
, and arithmetic expansion.
Below is a quick reference table that describes Bash arithmetic operators and their functionality.
Syntax | Description |
---|---|
++x , x++ | Pre and post-increment. |
--x , x-- | Pre and post-decrement. |
+ , - , * , / | Addition, subtraction, multiplication, division. |
% , ** (or ^ ) | Modulo (remainder) and exponentiation. |
&& , || , ! | Logical AND, OR, and negation. |
& , | , ^ , ~ | Bitwise AND, OR, XOR, and negation. |
<= , < , > , => | Less than or equal to, less than, greater than, and greater than or equal to comparison operators. |
== , != | Equality and inequality comparison operators. |
= | Assignment operator. Combines with other arithmetic operators. |
How to Do Math in Bash
Bash offers different ways to perform math calculations depending on the type of problem.
Below are examples of some common problems which use Bash math functionalities or commands as a solution. Most examples use the Bash arithmetic expansion notation. The section also covers common Bash math errors and how to resolve them.
Math with Integers
The arithmetic expansion notation is the simplest to use and manipulate with when working with integers. For example, create an expression with variables and calculate the result immediately:
echo $((x=2, y=3, x+y))
To evaluate multiple expressions, use compound notation, store each calculation in a variable, and echo the result. For example:
((x=2, y=3, a=x+y, b=x*y, c=x**y)); echo $a, $b, $c
When trying to divide, keep the following in mind:
1. Division by zero (0) is impossible and throws an error.
2. Bash arithmetic expansion does not support floating-point arithmetic. When attempting to divide in this case, the output shows zero (0).
The result of integer division must be an integer.
Incrementing and Decrementing
Bash arithmetic expansion uses C-style integer incrementing and decrementing. The operator for incrementing or decrementing is either before or after the variable, yielding different behavior.
If the operator is before the variable (++x
or --x
), the increment or decrement happens before value assignment. To see how pre-incrementing works, run the following lines:
number=1
echo $((++number))
The variable increments, and the new value is immediately available.
If the operator is after the variable (x++
or x--
), the increment or decrement happens after value assignment. To see how post-incrementing works, run the following:
number=1
echo $((number++))
echo $number
The variable stays the same and increments in the following use.
Floating-point Arithmetic
Although Bash arithmetic expansion does not support floating-point arithmetic, there are other ways to perform such calculations. Below are four examples using commands or programming languages available on most Linux systems.
1. Using awk
for up to 6 decimal places:
awk 'BEGIN { x = 2.3; y = 3.2; print "x * y = "(x * y) }'
2. Using bc
with the -l
flag for up to 20 decimal places:
echo "2.3 * 3.2" | bc -l
3. Using Perl for up to 20 decimal places:
perl -e 'print 2.3*3.2'
Perl often comes preinstalled in Linux systems.
4. Using printf and arithmetic expansion to convert a fraction to a decimal:
printf %.<precision>f "$((10**<multiplier> * <fraction>))e-<multiplier>"
Precision dictates how many decimal places, whereas the multiplier is a power of ten. The number should be lower than the multiplier. Otherwise, the formula puts trailing zeros in the result.
For example, convert 1/3 to a decimal with precision two:
printf %.2f "$((10**3 * 1/3))e-3"
Avoid this method for precise calculations and use it only for a small number of decimal places.
Calculating a Percentage and Rounding
Below are two ways to calculate a percentage in Bash.
1. Use printf
with arithmetic expansion.
printf %.2f "$((10**4 * part/total))e-4"%
For example, calculate what percent 40 is from 71:
printf %.2f%% "$((10**4 * 40/71))e-4"%
The precision is limited to two decimal places, and the answer always rounds down.
2. Use awk
with printf
for better precision:
awk 'BEGIN { printf "%.2f%%", (part/total*100) }'
For instance, calculate how many percent is 40 from 71 with:
awk 'BEGIN { printf "%.2f%%", (40/71*100) }'
The answer rounds up if the third decimal place is higher than five, providing better accuracy.
Finding a Factorial in the Shell
To calculate a factorial for any number, use a recursive Bash function.
For small numbers, Bash arithmetic expansion works well:
factorial () {
if (($1 > 1))
then
echo $(( $( factorial $(($1 - 1)) ) * $1 ))
else
echo 1
return
fi
}
To check the factorial for a number, use the following syntax:
factorial 5
The method is slow and has limited precision (up to factorial 20).
For higher precision, faster results, and larger numbers, use the bc
command. For example:
echo 'define factorial(x) {if (x>1){return x*factorial(x-1)};return 1}
factorial(<number>)' | bc
Replace <number>
with the factorial number to calculate. For example, to find the factorial of 50, use:
echo 'define factorial(x) {if (x>1){return x*factorial(x-1)};return 1} factorial(50)' | bc
The output prints the calculation result to the terminal.
Creating a Bash Calculator Function
Create a simple Bash calculator function with the following code:
calculate() { printf "%s\n" "$@" | bc -l; }
The function takes user input and pipes the equation into the bc
command.
Alternatively, to avoid using programs, use Bash arithmetic expansion in a function:
calculate() { echo $(("$@")); }
Keep the arithmetic expansion limitations in mind. Floating-point arithmetic is not available with this function.
Save the function into the .bashrc file to always have the function available in the shell.
Using Different Arithmetic Bases
By default, Bash arithmetic expansion uses base ten numbers. To change the number base, use the following format:
base#number
Where base is any integer between two and 64.
For example, to do a binary (base 2) calculation, use:
echo $((2#1010+2#1010))
Octal (base 8) calculations use a 0 prefix as an alias. For example:
echo $((010+010))
Hexadecimal (base 16) calculations allow using 0x as a base prefix. For example:
echo $((0xA+0xA))
The output prints the result in base ten for any calculation.
Convert Units
Create a simple Bash script to convert units:
1. Open a text editor, such as Vim, and create a convert.sh script. For example:
vim convert.sh
2. Paste the following code:
#!/bin/bash
## Program for feet and inches conversion
echo "Enter a number to be converted:"
read number
echo $number feet to inches:
echo "$number*12" | bc -l
echo $number inches to feet:
echo "$number/12" | bc -l
The program uses Bash read to take user input and calculates the conversion from feet to inches and from inches to feet.
3. Save the script and close:
:wq
4. Run the Bash script with:
. convert.sh
Enter a number and see the result. For different conversions, use appropriate conversion formulas.
Solving "bash error: value too great for base"
When working with different number bases, stay within the number base limits. For example, binary numbers use 0 and 1 to define numbers:
echo $((2#2+2#2))
Attempting to use 2#2
as a number outputs an error:
bash: 2#2: value too great for base (error token is "2#2")
The number is not the correct format for binary use. To resolve the error, convert the number to binary to perform the calculation correctly:
echo $((2#10+2#10))
The binary number 10
is 2
in base ten.
Solving "syntax error: invalid arithmetic operator"
The Bash arithmetic expansion notation only works for integer calculations. Attempt to add two floating-point numbers, for example:
echo $((2.1+2.1))
The command prints an error:
bash: 2.1+2.1: syntax error: invalid arithmetic operator (error token is ".1+2.1")
To resolve the error, use regular integer arithmetic or a different method to calculate the equation.
Solving "bash error: integer expression expected"
When comparing two numbers, the test
command requires integers. For example, try the following command:
[ 1 -gt 1.5 ]
The output prints an error:
bash: [: 1.5: integer expression expected
Resolve the error by comparing integer values.
Note: Learn about mathematical operations in Python by exploring two methods to calculate the power of a number in our guide Python Power Operator and Function.
Conclusion
You know how to do Bash arithmetic and various calculations through Bash scripting.
For more advanced scientific calculations, use Python together with SciPy, NumPy, and other libraries.