Difference between let, expr and $[]
All of these deal with arithmetic, but in different ways and the variable is created via different means. Some of these are specific to bash
shells, while others aren't.
$((...))
is called arithmetic expansion, which is typical of thebash
andksh
shells. This allows doing simple integer arithmetic, no floating point stuff though. The result of the expression replaces the expression, as inecho $((1+1))
would becomeecho 2
((...))
is referred to as arithmetic evaluation and can be used as part ofif ((...)); then
orwhile ((...)) ; do
statements. Arithmetic expansion$((..))
substitutes the output of the operation and can be used to assign variables as ini=$((i+1))
but cannot be used in conditional statements.$[...]
is the old syntax for arithmetic expansion which is deprecated. See also. This was likely kept so that oldbash
scripts don't break. This didn't work inksh93
, so my guess is that this syntax is bash-specific. NOTE: spaces are very important here; don't confuse$[1+1]
with stuff like[ $a -eq $b ]
. The[
with spaces is known as thetest
command, and you typically see it in decision-making parts. It is very different in behavior and purpose.let
is abash
andksh
keyword which allows for variable creation with simple arithmetic evaluation. If you try to assign a string there likelet a="hello world"
you'll get a syntax error. Works inbash
andksh93
.$(...)
is command substitution, where you literally take the output of a command and assign to a variable. Your command here isexpr
, which takes positional arguments, likeexpr arg1 arg2 arg3
, so spaces are important. It's sort of like a small command-line calculator for integer arithmetic, plus some true/false and regex type of stuff. This is a shell-neutral command.
It's also worth noting that arithmetic expansion and command substitution are specified by POSIX standard, while let
and $[...]
aren't.
let
command performs arithmetic evaluation and is a shell built-in.Run this command and you get nothing (only evaluates):
let 1+2
$(( ))
is used to perform arithmetic expansion: read hereRun this one and you'll get an error (because of expansion):
$((1+2))
$[ ]
is the old syntax for arithmetic expansion:The old format $[expression] is deprecated and will be removed in upcoming of bash. Bash Man Page
expr
is a binary command, if you want to do arithmetic expansion within a command subsituation you can use it:echo $(expr 1 + 2) echo `expr 1 + 2`
Since some of the answers above specifically mention ksh93
it's worth noting that it can do floating point math, e.g.:
$ print $((1.0/3))
0.333333333333333333
You can control the precision of the output with printf, e.g.:
$ printf "%.4f\n" $((1.0/3))
0.3333
At least one argument must be specified as a floating-point number as above. If both are specified as integers then only integer math is done, e.g.:
$ print $((1/3))
0
This can be helpful when you need floating point math in a shell script since you can avoid calling an external command.