Bash math refers to the mathematical operations you can conduct on the Linux terminal. Normally, you wouldn’t associate bash with math operations – after all, why would you choose to type in clunky commands on the terminal, when you could open a calculator instead? However, there are some surprisingly useful use case scenarios where it helps to know how to perform bash math. I’ll explore several of these situations in this article.
Bash math also has some fundamental limitations, particularly when it comes to floating-point arithmetic. It’s also simple and not suitable for more advanced operations, which ties it with its utility for OS-related tasks. Finally, bash math expressions can be complicated to read and debug compared to what we see in other programming languages, so we should use them sparingly.
How to Perform Bash Math
First, let’s look at the syntax for bash math. There are several ways to accomplish the same thing.
Basic Arithmetic
Here’s how to use bash math for simple arithmetic operations:
result=$((5 + 3))
echo "5 + 3 = $result"
And here’s the output:
In the above example, we use a standard arithmetic operator – the double parentheses with a dollar sign – $(()) – to encapsulate the math expression we want to use in bash. Within these double brackets, we can even use variables without needing to classify them as such with dollar signs ($). So the following would work as well:
x=4
echo $((x+3))
Here’s how it performs:
I don’t need to use $x while the variable is inside the double parenthesis. This makes reading and writing expressions just a little bit easier.
The Legacy “expr” Keyword
Before bash was introduced, the “expr” command was used for mathematical operations. We don’t use it anymore, because the $(( )) construction is so much more convenient, but we can still use “expr” today for basic math operations. For example:
expr 5 \* 3
Here’s the output:
As you can see, the whole thing is very clumsy. We even need to escape (\) the asterisk sign because Linux treats it as a special character. However, the tool did find some use because it allowed easy operations for evaluating the length of strings and finding the index of substrings. But these days, no one uses expr. Expr also has the side-effect of spawning a subshell for its operations, which can have unintended consequences.
Using the “bc” Command
The “bc” command is used in Linux for complex mathematical operations. For example, you can’t directly find the square root of a number in bash. But using bc, you can. There are two ways to use bc – as a standalone tool, or as part of a bash command.
As a standalone tool, you invoke it directly using:
bc
And then you type in your expressions. For example:
In the above example, typing “bc” opens a dedicated interface where you can type in commands. As you can see, it’s nothing special. You can type “sqrt(16) and get the answer immediately, or you can type in simpler expressions.
But the better way to use bc is directly from the terminal. For example:
echo "sqrt(16)" | bc
In the above command, I create a string with the expression I want – in this case, sqrt(16) – and pipe the command to bc. This is the only way to use bc on the terminal and get an immediate answer without entering the tool directly as we saw before. bc takes no direct arguments and only accepts input from either a file or a string.
The benefit of bc is that we can use it for floating point operations since the default bash tool doesn’t do a good enough job.
Math Expressions in Conditional Statements
In addition to regular commands, you can also use conditional statements in Bash that evaluate mathematical expressions. For example, look at the following lines:
if ((5 > 3)); then
echo "5 is greater than 3"
fi
The (( )) operator, evaluates a mathematical expression and returns “1” if the boolean expression evaluates to be true, and “0”, if it evaluates to be false. If true, the statements within the if…fi loop are invoked. Here’s what it looks like:
You might think that there’s no use for something like this directly on the bash terminal, and you would be right. However, this kind of control statement is very common in bash scripts and they’re a key reason why bash is so powerful.
Use of Bash Math in Loops
In addition to control scripts, you can also use bash math in loops. For example:
sum=0
for i in {1..10}; do
sum=$((sum + i))
done
echo "Sum of 1 to 10 = $sum"
The above code will add the numbers from 1 to 10. Like the previous section on control statements, you’ll not need to do this directly in the bash terminal, but it’s useful in scripts. For example, if you want to find the sum of the disk usage of certain types of files that start with a particular string in a folder, a loop like this can give you the result quickly.
Limitations of Bash Math for Floating Point Calculations
Mathematical operations in bash have a serious shortcoming – they only perform integer calculations. This means that if the output of a calculation is fractional, bash will simply discard the fractional part. Note that this means it doesn’t matter how close a fraction is to a particular integer, bash will discard anything after the point (.).
Consider the following statement:
echo $((290 / 100))
What do you think this will output? Of course, the correct answer is 2.9 and you would expect bash to at least round it up to 3 if it wants to avoid fractions. Instead, we get this:
As you can see, despite the correct answer being far closer to 3 than it is to 2, bash simply discards the fraction and only prints the integer part. In the course of a long calculation, these errors can multiply as bash only carries forward the integer at each step while evaluating longer expressions. For example:
echo $((290 / 100 * 10))
The correct answer is 29, but here is what bash prints:
Since the first expression evaluates to “2”, that is what carries forward and the final answer is 20 instead of 29. If the second operator is an exponent, the error will propagate even faster.
For this reason, you shouldn’t use bash math for anything that might include either floating-point numbers or for calculations that have the potential to propagate errors. If you need floating point calculations, it’s better to use bc instead.
Conclusion
Bash math is useful for basic calculations in scripts, where there’s not much potential for things to go wrong with floating points. If you’re working with integers like string lengths or the number of files in a directory, ordinary bash math will work just fine. However, if you need to work with integers like maybe file sizes, or seconds where milliseconds are important, then you can use bc to extend the math capabilities of bash.
While you won’t have much occasion to use bash math directly on the terminal, it’s invaluable in scripts, where you can expand it with control and loop statements.
I’m a NameHero team member, and an expert on WordPress and web hosting. I’ve been in this industry since 2008. I’ve also developed apps on Android and have written extensive tutorials on managing Linux servers. You can contact me on my website WP-Tweaks.com!
Leave a Reply