let is a builtin function of Bash that allows us to do simple arithmetic. It follows the basic format:
let <arithmetic expression>
The arithmetic expression can take a variety of formats which we'll outline below. The first part is generally always a variable which the result is saved into however.
Let's look at a simple example:
let_example.sh
#!/bin/bash
# Basic arithmetic using let
let a=5+4
echo $a # 9
let “a = 5 + 4”
echo $a # 9
let a++
echo $a # 10
let “a = 4 * 5”
echo $a # 20
let “a = $1 + 30”
echo $a # 30 + first command line argument
Let's break it down:
let a=5+4
This is the basic format. Note that if we don't put quotes around the expression then it must be written with no spaces.
let “a = 5 + 4”
This time we have used quotes which allow us to space out the expression to make it more readable.
let a++
This is a shorthand for increment the value of the variable a by 1. It is the same as writing “a = a + 1”.
let “a = $1 + 30”
We may also include other variables in the expression.
./let_example.sh 15
9
9
10
20
45
Here is a table with some of the basic expressions you may perform. There are others but these are the most commonly used.
Operator Operation +, -, \*, / addition, subtraction, multiply, divide var++ Increase the variable var by 1 var– Decrease the variable var by 1 % Modulus (Return the remainder after division) These operators may be used in the other mechanisms described below as well.
Expr
expr is similar to let except instead of saving the result to a variable it instead prints the answer.
Unlike let you don't need to enclose the expression in quotes. You also must have spaces between the items of the expression. It is also common to use expr within command substitution to save the output to a variable.
expr item1 operator item2
Let's look at a simple example:
expr_example.sh
#!/bin/bash
# Basic arithmetic using expr
expr 5 + 4
expr “5 + 4”
expr 5+4
expr 5 \* $1
expr 11 % 2
a=$( expr 10 - 3 )
echo $a # 7
expr 5 + 4
This is the basic format. Note that there must be spaces between the items and no quotes.
expr “5 + 4”
If we do put quotes around the expression then the expression will not be evaluated but printed instead.
expr 5+4
If we do not put spaces between the items of the expression then the expression will not be evaluated but printed instead.
expr 5 \* $1
Some characters have a special meaning to Bash so we must escape them (put a backslash in front of) to remove their special meaning.
expr 11 % 2
Here we demonstrate the operator modulus. The modulus is the remainder when the first item is divided by the second item.
a=$( expr 10 - 3 )
This time we're using expr within command substitution in order to save the result to the variable a.
./expr_example.sh 12
9
5 + 4
5+4
60
1
7
Double Parentheses
In the section on Variables we saw that we could save the output of a command easily to a variable. It turns out that this mechanism is also able to do basic arithmetic for us if we tweak the syntax a little. We do so by using double brackets like so:
$(( expression ))
Here's an example to illustrate:
expansion_example.sh
#!/bin/bash
# Basic arithmetic using double parentheses
a=$(( 4 + 5 ))
echo $a # 9
a=$((3+5))
echo $a # 8
b=$(( a + 3 ))
echo $b # 11
b=$(( $a + 4 ))
echo $b # 12
(( b++ ))
echo $b # 13
(( b += 3 ))
echo $b # 16
a=$(( 4 * 5 ))
echo $a # 20
Let's break it down:
a=$(( 4 + 5 ))
This is the basic format. As you can see we may space it out nicely for readability without the need for quotes.
a=$((3+5))
As you can see, it works just the same if we take spacing out.
b=$(( a + 3 ))
We may include variables without the preceding $ sign.
b=$(( $a + 4 ))
Variables can be included with the $ sign if you prefer.
(( b++ ))
This is a slightly different form. Here the value of the variable b is incremented by 1 (using the same mechanism illustrated under let). When we do this we don't need the $ sign preceding the brackets.
(( b += 3 ))
This is a slightly different form of the previous example. Here the value of the variable b is incremented by 3. It is a shorthand for b = b + 3.
Unlike other methods, when we do multiplication we don't need to escape the * sign.
./expansion_example.sh
9
8
11
12
13
16
20
So as you can see double parentheses is quite flexible in how you format it's expression. This is part of why we prefer this method. As double parentheses is builtin to Bash it also runs slighly more efficiently (though to be honest, with the raw computing power of machines these days the difference in performance is really insignificant).
Length of a Variable
This isn't really arithmetic but it can be quite useful. If you want to find out the lengh of a variable (how many characters) you can do the following:
${#variable}
Here's an example:
length_example.sh
#!/bin/bash
# Show the length of a variable.
a='Hello World'
echo ${#a} # 11
b=4953
echo ${#b} # 4
./length_example.sh
11
4
Summary
let expression
Make a variable equal to an expression.
expr expression
print out the result of the expression.
$(( expression ))
Return the result of the expression.
${#var}
Return the length of the variable var.
Arithmetic
There are several ways in which to do arithmetic in Bash scripts. Double parentheses is the preferred method.
Formatting
When doing arithmetic, the presence or absence of spaces (and quotes) is often important.
Activities
Let's dive in with arithmetic.
Create a simple script which will take two command line arguments and then multiply them together using each of the methods detailed above.
Write a Bash script which will print tomorrows date. (Hint: use the command date)
Remember when we looked at variables we discovered $RANDOM will return a random number. This number is between 0 and 32767 which is not always the most useful. Let's write a script which will use this variable and some arithmetic (hint: play with modulus) to return a random number between 0 and 100.
Now let's play with the previous script. Modify it so that you can specify as a command line argument the upper limit of the random number.
Can you make it so that a lower limit can be specified also? eg. if I ran ./random.sh 10 45 it would only return random numbers between 10 and 45.