Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How to increment a numeric variable in bash? I tried with var=$var+1 and var=($var+1) but it doesn't work. My variable is a number, but bash think that is a string. My bash version is 4.2.45(1)-release (x86_64-pc-linux-gnu) and I use Ubuntu 13.10.

share|improve this question
up vote 267 down vote accepted

There are more than one way to increment a variable in bash, but what you tried is not correct.

You can use for example arithmetic expansion:

var=$((var+1))

or only:

((var=var+1))

or:

((var+=1))

or even:

((var++))

Or you can use let:

let "var=var+1"

or only:

let "var+=1"

or even:

let "var++"

See also: http://tldp.org/LDP/abs/html/dblparens.html.

share|improve this answer
8  
or ((++var)) or ((var=var+1)) or ((var+=1)). – gniourf_gniourf Dec 3 '13 at 18:30
    
or var=$(expr $var + 1) – chilicuil Dec 3 '13 at 23:20
    
Curiously, var=0; ((var++)) returns an error code while var=0; ((var++)); ((var++)) does not. Any idea why? – phunehehe Mar 26 '14 at 9:36
    
@RaduRădeanu I'm sure, the same thing happens in zsh too. Actually maybe I didn't make myself clear. This prints 1 (an error code) instead of 0 (successful): var=0; ((var++)); echo $?. – phunehehe Mar 27 '14 at 11:08
6  
@phunehehe Look at help '(('. The last line says: Returns 1 if EXPRESSION evaluates to 0; returns 0 otherwise. – Radu Rădeanu Mar 27 '14 at 11:41
var=$((var + 1))

Arithmetic in bash uses $((...)) syntax.

share|improve this answer
    
Vastly better than the accepted answer. In just 10% as much space, you managed to provide enough examples (one is plenty - nine is overkill to the point when you're just showing off), and you provided us with enough info to know that ((...)) is the key to using arithmetic in bash. I didn't realize that just looking at the accepted answer - I thought there was a weird set of rules about order of operations or something leading to all of the parenthesis in the accepted answer. – ArtOfWarfare Jun 22 at 13:56

Performance Analysis of various options

Thanks to Radu Rădeanu answer that provides the following list of ways to increment a variable in bash.

  • var=$((var+1))
    
  • ((var=var+1))
    
  • ((var+=1))
    
  • ((var++))
    
  • let "var=var+1"
    
  • let "var+=1" 
    
  • let "var++"
    

Having so many options leads to these two questions:

  1. Is there a performance difference between them?
  2. If so which, which performs best?

Incremental performance test code:

#!/bin/bash

# To focus exclusively on the performance of each type of increment
# statement, we should exclude bash performing while loops from the
# performance measure. So, lets time 7 individual scripts that
# increment $i in their own unique way. 
x=0
until [ $x = "10000000" ]; do
    echo 'i=$((i+1))' >> t0
    echo '((i=i+1))' >> t1
    echo '((i+=1))' >> t2
    echo '((i++))' >> t3
    echo 'let "i=i+1"'>> t4
    echo 'let "i+=1"' >> t5
    echo 'let "i++"' >> t6
    ((x++))
done

chmod +x t0 t1 t2 t3 t4 t5 t6

echo -n 'i=$((i+1)) '; { time ./t0 ;} |& grep user
echo -n '((i=i+1))  '; { time ./t1 ;} |& grep user
echo -n '((i+=1))   '; { time ./t2 ;} |& grep user
echo -n '((i++))    '; { time ./t3 ;}|& grep user
echo -n 'let "i=i+1"    '; { time ./t4 ;} |& grep user
echo -n 'let "i+=1" '; { time ./t5 ;} |& grep user
echo -n 'let "i++"  '; { time ./t6 ;} |& grep user
rm t0 t1 t2 t3 t4 t5 t6

Results:

i=$((i+1))  user    1m20.797s
((i=i+1))   user    1m3.912s
((i+=1))    user    1m0.430s
((i++))     user    0m53.694s
let "i=i+1" user    1m49.539s
let "i+=1"  user    1m46.535s
let "i++"   user    1m40.828s

Looking through the comments, one can also find several other ways to increment a variable in bash. ((++i)) performed very similar to ((i++)) and i=(expr $i +1) performed similar to let statements

Conclusion:

It seems bash is fastest at performing ((i++)). let and expr statements seem particularly slow.

share|improve this answer

There's also this:

var=`expr $var + 1`

Take careful note of the spaces and also ` is not '

While Radu's answers, and the comments, are exhaustive and very helpful, they are bash-specific. I know you did specifically ask about bash, but I thought I'd pipe in since I found this question when I was looking to do the same thing using sh in busybox under uCLinux. This portable beyond bash.

share|improve this answer

There's one method missing in all the answers - bc

$ VAR=7                                                                   

xieerqi:
$ bc <<< "$VAR+2"                                                         
9

$ echo $VAR                                                               
7

xieerqi:
$ VAR=$( bc <<< "$VAR+1" )

xieerqi:
$ echo $VAR                                                               
8
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.