Arithmetic in the Shell

@igor_sarcevic ·

I remember the first time I tried to use the shell. It was weird that I had to type in things and not just click around to get things done. But gradually I got used to it, and after a while it became my primary way to interact with my computer.

It didn’t pass much time till I figured out that the commands that I am typing in are actually part of a programming language named Bash. That of course changed everything! Starting from that moment I could combine the thing I love ( programming ) with the boring chore of keeping my system in a sane condition. That moment a new kind of passion for computers was born in my hearth.

But wait! If Bash is a programming language it must be able to count and do basic arithmetic. This article is precisely about that — calculations in the shell.

Expr

This task is actually really simple, but there are as always in Unix, several ways to do it. The oldest method is to use expr to evaluate expressions. For example to add 2 and 4 we can write the following:

$ expr 2 + 4
6

This seems really easy, but there is a catch. If you try to multiply numbers using * Bash will throw you back an error:

$ expr 2 * 4
expr: syntax error

In this case Bash sees * as wildcard operator so you must use a backslash before the asterisk sign:

$ expr 2 \* 4
8

At this point you will probably try to surround the expression with quotes, but that will also fail:

$ expr "2 * 4"
2 * 4

$ expr '2 * 4'
2 * 4

Apart from this little annoyance, expr is quite powerful. It can even do boolean arithmetic:

$ expr 2 \< 4
1

$ expr 4 \< 2
0

Arithmetic expansion

There exists a better alternative for expr but is unfortunately not available in the original Bourne Shell only in the POSIX compliant one — arithmetic expansion.

It can also, like expr, take an arithmetic expression, but instead of printing out the result, it will substitute itself with the resulting value. To print out the result we must use echo or print. For example to multiply 2 and 4 we can write the following:

$ echo $(( 4 * 2 ))
8

Without an echo this command would fail with:

$ $(( 4 * 2 ))
sh: 1: 8: not found

As you can see in the above example, Bash tried to execute the result of the expression as a standard command.

Note: There is an older variant of arithmetic expansion that uses the following less verbose form $[ 1 + 4 ] but is now deprecated.

Euclid’s Algorithm in the Shell

Now let’s do something more challenging and try to implement Euclid’s greatest common divisor algorithm in a shell script.

Note: This part will be a little bit advanced and will require you to be familiar with other common things in Bash like loops and variables.

Let’s start by creating a shell script and giving it executable permissions:

$ touch gcd.sh
$ chmod +x gcd.sh

My goal is to invoke my script with two command line arguments and expect it to print out the greatest common divisor like this:

$ ./gcd.sh 14 4
2

To achieve this we will first need to capture the two incoming numbers with $1 and $2:

#!/bin/sh

a=$1
b=$2

The remainder of the script is the basic implementation of the Euclid’s algorithm that I presume every programmer recognizes:

#!/bin/sh

a=$1
b=$2

while [ $b -ne 0 ]; do
  remainder=$(( $a % $b ))
  a=$b
  b=$remainder
done

echo $a

Note: Shame on you if you don’t recognize the following algorithm, go and Google it. This is probably the most basic algorithm out there. Also, sorry for the harsh words :3

Final words

I hope you enjoyed this article and also that I have shown you something new and exciting.

Stay awesome!

By the way, I started using drawing tablet instead of the old paper + photo + gimp approach. I hope you like this new art style.