9.7. The Double Parentheses Construct

Similar to the let command, the (( ... )) construct permits arithmetic expansion and evaluation. In its simplest form, a=$(( 5 + 3 )) would set a to 5 + 3, or 8. However, this double parentheses construct is also a mechanism for allowing C-style manipulation of variables in Bash, for example, (( var++ )).


Example 9-31. C-style manipulation of variables

   1 #!/bin/bash
   2 # Manipulating a variable, C-style, using the ((...)) construct.
   3 
   4 
   5 echo
   6 
   7 (( a = 23 ))  #  Setting a value, C-style,
   8               #+ with spaces on both sides of the "=".
   9 echo "a (initial value) = $a"
  10 
  11 (( a++ ))     #  Post-increment 'a', C-style.
  12 echo "a (after a++) = $a"
  13 
  14 (( a-- ))     #  Post-decrement 'a', C-style.
  15 echo "a (after a--) = $a"
  16 
  17 
  18 (( ++a ))     #  Pre-increment 'a', C-style.
  19 echo "a (after ++a) = $a"
  20 
  21 (( --a ))     #  Pre-decrement 'a', C-style.
  22 echo "a (after --a) = $a"
  23 
  24 echo
  25 
  26 ########################################################
  27 #  Note that, as in C, pre- and post-decrement operators
  28 #+ have slightly different side-effects.
  29 
  30 n=1; let --n && echo "True" || echo "False"  # False
  31 n=1; let n-- && echo "True" || echo "False"  # True
  32 
  33 #  Thanks, Jeroen Domburg.
  34 ########################################################
  35 
  36 echo
  37 
  38 (( t = a<45?7:11 ))   # C-style trinary operator.
  39 echo "If a < 45, then t = 7, else t = 11."
  40 echo "t = $t "        # Yes!
  41 
  42 echo
  43 
  44 
  45 # -----------------
  46 # Easter Egg alert!
  47 # -----------------
  48 #  Chet Ramey apparently snuck a bunch of undocumented C-style constructs
  49 #+ into Bash (actually adapted from ksh, pretty much).
  50 #  In the Bash docs, Ramey calls ((...)) shell arithmetic,
  51 #+ but it goes far beyond that.
  52 #  Sorry, Chet, the secret is now out.
  53 
  54 # See also "for" and "while" loops using the ((...)) construct.
  55 
  56 # These work only with Bash, version 2.04 or later.
  57 
  58 exit 0

See also Example 10-12 and Example 8-4.