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-type manipulation of variables in Bash.


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

See also Example 10-12.