Let’s do some Bash Math!
While writing your bash scripts, you will often find yourself wanting to figure out the result of an arithmetic calculation to determine a remaining disk space, file sizes, password expiry dates, number of hosts, network bandwidth, etc.
In this chapter of the bash beginner series, you will learn to use bash operators to carry out various arithmetic calculations.
To refresh your memory, here are the arithmetic operators in bash:
Performing addition and subtraction in bash scripts
Let’s create a bash script named addition.sh that will simply add two file sizes (in bytes) and display the output.
You must be familiar with arguments in bash scripts by now. I do hope you are also familiar with the cut and du commands.
The du command gives you the size of the file along . The output has both the file size and the file name. This is where cut command is used to extract the first column (i.e. the file size) from the output. Output of the du command is passed to cut command using pipe redirection.
Here's the script:
#!/bin/bash fs1=$(du -b $1 | cut -f1) fs2=$(du -b $2 | cut -f1) echo "File size of $1 is: $fs1" echo "File size of $2 is: $fs2" total=$(($fs1 + $fs2)) echo "Total size is: $total"
Notice that you will pass the two filenames as arguments to the script. For example, here I run the script and pass the two files /etc/passwd and /etc/group as arguments:
kabary@skillcreed:~/scripts$ ./addition.sh /etc/passwd /etc/group File size of /etc/passwd is: 2795 File size of /etc/group is: 1065 Total size is: 3860
The most important line in the addition.sh script is:
total=$(($fs1 + $fs2))
Where you used the + operator to add the two numbers $fs1 and $fs2. Notice also that to evaluate any arithmetic expression you have to enclose between double parenthesis as follows:
You can also use the minus operator (-) to for subtraction. For example, the value of the sub variable in the following statement will result to seven:
Performing multiplication and division in bash scripts
Let’s create a bash script named giga2mega.sh that will convert Gigabytes (GB) to Megabytes (MB):
#!/bin/bash GIGA=$1 MEGA=$(($GIGA * 1024)) echo "$GIGA GB is equal to $MEGA MB"
Now let’s run the script to find out how many Megabytes are there in four Gigabytes:
kabary@skillcreed:~/scripts$ ./giga2mega.sh 4 4 GB is equal to 4096 MB
Here I used the multiplication (*) operator to multiply the number of Gigabytes by 1024 to get the Megabytes equivalent:
MEGA=$(($GIGA * 1024))
It’s easy to add more functionality to this script to convert Gigabytes (GB) to Kilobytes (KB):
KILO=$(($GIGA * 1024 * 1024))
I will let you convert Gigabytes to bytes as a practice exercise!
You can also use the division operator (/) to divide two numbers. For example, the value of the div variable in the following statement will evaluate to five:
div=$((20 / 4))
Notice that this is integer division and so all fractions are lost. For instance, if you divide 5 by 2, you will get 2 which is incorrect, of course:
kabary@skillcreed:~/scripts$ div=$((5 / 2)) kabary@skillcreed:~/scripts$ echo $div 2
To get a decimal output; you can make use of the bc command. For example, to divide 5 by 2 with the bc command, you can use the following statement:
echo "5/2" | bc -l 2.50000000000000000000
Notice that you can use other operators as well with the bc command whenever you are dealing with decimal numbers:
Using power and remainder (modulo)
Let’s create a power calculator! I am going to create a script named power.sh that will accept two numbers a and b (as arguments) and it will display the result of a raised to the power of b:
#!/bin/bash a=$1 b=$2 result=$((a**b)) echo "$1^$2=$result"
Notice that I use the exponentiation operator (**) to calculate the result of a raised to the power of b.
Let’s do a few runs of the script to make sure that it yields the correct answers:
kabary@skillcreed:~/scripts$ ./power.sh 2 3 2^3=8 kabary@skillcreed:~/scripts$ ./power.sh 3 2 3^2=9 kabary@skillcreed:~/scripts$ ./power.sh 5 2 5^2=25 kabary@skillcreed:~/scripts$ ./power.sh 4 2 4^2=16
You can also use the modulo operator (%) to calculate integer remainders. For instance, the value of the rem variable in the following statement will evaluate to 2:
The remainder here is 2 because 5 goes into 17 three times, and two remains!
Practice Time: Make a Degree Converter bash script
Let's wrap up this tutorial by creating a script named c2f.sh that will convert Celsius degrees to Fahrenheit degrees using the equation below:
F = C x (9/5) + 32
This will be a good exercise for you to try the new things you just learned in this bash tutorial.
Here's a solution (there could be several ways to achieve the same result):
#!/bin/bash C=$1 F=$(echo "scale=2; $C * (9/5) + 32" | bc -l) echo "$C degrees Celsius is equal to $F degrees Fahrenheit."
I used the bc command because we are dealing with decimals and I also used "scale=2" to display the output in two decimal points.
Let’s do a few runs of the script to make sure it is outputting the correct results:
kabary@skillcreed:~/scripts$ ./c2f.sh 2 2 degrees Celsius is equal to 35.60 degrees Fahrenheit. kabary@skillcreed:~/scripts$ ./c2f.sh -3 -3 degrees Celsius is equal to 26.60 degrees Fahrenheit. kabary@skillcreed:~/scripts$ ./c2f.sh 27 27 degrees Celsius is equal to 80.60 degrees Fahrenheit.
Perfect! This brings us to the end of this tutorial. I hope you have enjoyed doing some math with bash and stay tuned for next tutorial in the bash beginner series as you will learn how to manipulate strings!