Use $(( )) or let for integer arithmetic expressions.
COUNT=$((COUNT + 5 + MAX * 2)) let COUNT+=5+MAX*2
As long as you keep to integer arithmetic, you can use all the standard (i.e., C-like)
operators inside of $(()) for arithmetic. There is one additional
operator—you can use ** for raising to a power, as in MAX=$((2**8))
, which yields 256.
Spaces are not needed nor are they prohibited around operators and arguments (though ** must be together) within a $(( )) expression. But you must not have spaces around the equals sign, as with any bash variable assignment. If you wrote:
COUNT = $((COUNT + 5)) # not what you think!
then bash will try to run a program named
COUNT and its first argument would be an equal
sign, and its second argument would be the number you get adding
5
to the value of $COUNT
. Remember not to put spaces around the
equal sign.
Another oddity to these expressions is that the $ that we normally put in front of a shell variable to say
we want its value (as in $COUNT
or
$MAX
) is not needed inside the
double parentheses. For example, $((COUNT +5
MAX * 2))
needs no dollar sign on the shell variables—in
effect, the outer $ applies to the entire expression.
We do need the dollar sign, though, if we are using a positional
parameter (e.g.,$2
) to distinguish it
from a numeric constant (e.g., “2”). Here’s an example:
COUNT=$((COUNT + $2 + OFFSET))
There is a similar mechanism for integer arithmetic with shell
variables using the bash built-in let
statement. It uses the same arithmetic
operators as the $(()) construct:
let COUNT=COUNT+5
When using let
, there are some
fancy assignment operators we can use such as this (which will
accomplish the same thing as the previous line):
let COUNT+=5
(This should look familiar to programmers of C/C++ and Java.)
Table 6-1 shows a list of those special assignment operators.
Table 6-1. Explanation of assignment operators in bash
Operator | Operation with assignment | Use | Meaning |
---|---|---|---|
= | Simple assignment | | |
*= | Multiplication | | |
/= | Division | | |
%= | Remainder | | |
+= | Addition | | |
-= | Subtraction | | |
<<= | Bit-shift left | | |
>>= | Bit-shift right | | |
&= | Bitwise “and” | | |
^= | Bitwise “exclusive or” | | |
|= | Bitwise “or” | | |
These assignment operators are also available with $(( )) provided they occur inside the double parentheses. The outermost assignment is still just plain old shell variable assignment.
The assignments can also be cascaded, through the use of the comma operator:
echo $(( X+=5 , Y*=3 ))
which will do both assignments and then echo the result of the
second expression (since the comma operator returns the value of its
second expression). If you don’t want to echo the result, the more
common usage would be with the let
statement:
let X+=5 Y*=3
The comma operator is not needed here, as each word of a let
statement is its own arithmetic
expression.
Unlike many other places in bash scripts
where certain characters have special meanings (like the asterisk for
wildcard patterns or parentheses for subshell execution), in these
expressions we don’t need to use quotes or backslashes to escape them
since they don’t have their special meaning in let
statements or inside of the $(( ))
construct:
let Y=(X+2)*10 Y=$(( ( X + 2 ) * 10 ))
One other important difference between the let
statement and the $(( )) syntax deals with
the rather minor issue of the whitespace (i.e., the space character).
The let
statement requires that there
be no spaces around not only the assignment operator (the equal sign),
but around any of the other operators as well; it must all be packed
together into a single word.
The $(( )) syntax, however, Can be much more generous, allowing
all sorts of whitespace within the parentheses. For that reason, it is
both less prone to errors and makes the code much more readable and is,
therefore, our preferred way of doing bash integer
arithmetic. However, an exception can be made for the occasional
+=
assignment or ++
operator, or when we get nostalgic for the
early days of BASIC programming (which had a LET
statement).
3.17.76.175