Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
syntax:expansion:arith [2009/02/24 06:26]
127.0.0.1 external edit
syntax:expansion:arith [2013/01/08 14:49] (current)
ormaaj
Line 7: Line 7:
 </​code>​ </​code>​
  
-The [[syntax:​arith_expr | arithmetic expression]] ''<​EXPRESSION>''​ is evaluated and the resulting value replaces ​the whole ''<​nowiki>​$((...))</​nowiki>''​ construct:+The [[syntax:​arith_expr | arithmetic expression]] ''<​EXPRESSION>''​ is evaluated and expands to the result. The output of the arithmetic expansion is guaranteed to be one word and a digit in Bash.
  
 Please **do not use the second form ''​$[ ... ]''​**! It's deprecated. The preferred and standardized form is ''<​nowiki>​$(( ... ))</​nowiki>''​! Please **do not use the second form ''​$[ ... ]''​**! It's deprecated. The preferred and standardized form is ''<​nowiki>​$(( ... ))</​nowiki>''​!
  
-<​code>​ +Example 
-read -p "​Enter ​first operand: " ​first +<​code ​bash
-read -"Enter second operand: ​" ​second +function printSum { 
-echo "The sum is $((first + second))"+    typeset ​-A args 
 +    typeset name 
 +    for name in first second; do 
 +        [[ -t 0 ]] && printf 'Enter %s positive integer' ​"$name" >&2 
 +        read -r ${BASH_VERSION+-e} ​"args[$name]
 +        [[ ${args[$name]} == +([[:​digit:​]]) ]] || return 1 # Validation is extremely important whenever user input is used in arithmetic. 
 +    done 
 +    printf 'The sum is %d.' ​$((${args[first]} ${args[second]})) 
 +}
 </​code>​ </​code>​
  
-**Note** that in Bash you don't need the arithmetic expansion to simply ​check for a specific ​value of an integer, this can be done using the [[syntax:​ccmd:​arithmetic_eval | arithmetic evaluation compound command]]:+**Note** that in Bash you don't need the arithmetic expansion to check for the boolean ​value of an arithmetic expression. This can be done using the [[syntax:​ccmd:​arithmetic_eval | arithmetic evaluation compound command]]:
  
-<​code>​ +<​code ​bash
-read -p "Enter a number: ​"+printf %s 'Enter a number: ​' >&​2 
 +read -r number
 if ((number == 1234)); then if ((number == 1234)); then
-  ​echo "Good guess"+    ​echo 'Good guess'
 else else
-  ​echo "Haha... :-P"+    ​echo 'Haha... :-P'
 fi fi
 </​code>​ </​code>​
 +
 +**Variables** used inside the arithmetic expansion, as in all arithmetic contexts, can be used with or without variable expansion:
 +
 +<code bash>
 +x=1
 +
 +echo $((x)) ​      # Good.
 +echo $(($x)) ​     # Ok. Avoid expansions within arithmetic. Use variables directly.
 +echo $(("​$x"​)) ​   # Error. There is no quote-removal in arithmetic contexts. It expands to $(("​1"​)),​ which is an invalid arithmetic expression.
 +echo $((x[0])) ​   # Good.
 +echo $((${x[0]})) # Ok. Nested expansion again.
 +echo $((${x[$((${x[!$x]}-$x))]})) # Same as above but more ridiculous.
 +echo $(($x[0])) ​  # Error. This expands to $((1[0])), an invalid expression.
 +</​code>​
 +
 +===== Bugs and Portability considerations =====
 +  * The original Bourne shell doesn'​t have arithmetic expansions. You have to use something like ''​expr(1)''​ within backticks instead. Since ''​expr''​ is horrible (as are backticks), and arithmetic expansion is required by POSIX, you should not worry about this, and preferably fix any code you find that's still using ''​expr''​.
  
 ===== See also ===== ===== See also =====
 +  * [[syntax:​arith_expr | arithmetic expressions]]
 +  * [[syntax:​ccmd:​arithmetic_eval | arithmetic evaluation compound command]]
   * [[syntax:​expansion:​intro | Introduction to expansion and substitution]]   * [[syntax:​expansion:​intro | Introduction to expansion and substitution]]
 +  * [[http://​pubs.opengroup.org/​onlinepubs/​9699919799/​utilities/​V3_chap02.html#​tag_18_06_04 | POSIX definition]]
  
  • syntax/expansion/arith.1235456762.txt
  • Last modified: 2011/10/05 05:17
  • (external edit)