0

From bash manual

Shell variables are allowed as operands; parameter expansion is performed before the expression is evaluated. Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax. A shell variable that is null or unset evaluates to 0 when referenced by name without using the parameter expansion syntax. The value of a variable is evaluated as an arithmetic expression when it is referenced, or when a variable which has been given the integer attribute using ‘declare -i’ is assigned a value. A null value evaluates to 0. A shell variable need not have its integer attribute turned on to be used in an expression.

What does "The value of a variable is evaluated as an arithmetic expression when it is referenced, or when a variable which has been given the integer attribute using ‘declare -i’ is assigned a value" mean?

Is the variable assumed to be used as an operand in an arithmetic expression? var=3+4 alone will not be evaluated as an arithmetic expression.

Can you give an example for the case "when it is referenced", and an example for the case "when a variable which has been given the integer attribute using ‘declare -i’ is assigned a value"?

Thanks.

2

“When it is referenced” means “when it is used”, i.e. the context indicates that the variable’s value should be interpreted as a number:

$ i=Hello
$ echo ${i}
Hello
$ echo $((i + 1))
1

Here i obviously contains a string, but because it’s used in an arithmetic expression, it’s interpreted as an arithmetic expression. If Hello is unset or null here, then it becomes 0; you can try playing around with different values for i and Hello to see the effects (i=1+1, Hello=Hello etc.).

Variables with the integer attribute, i.e. variables declared using declare -i, are coerced to integers on assignment, not on use:

$ declare -i i
$ i=Hello
$ echo ${i}
0

Note that in all these cases, no errors are reported.

Integer-attribute variables can be used with arithmetic expressions without any syntactic sugar:

$ declare -i i
$ i=3+4
$ echo ${i}
7

which is a direct consequence of the fact that their assignments are interpreted as arithmetic expressions.

  • It's treated as 0 only if $Hello is unset or set to something that evaluates to 0. Hello is a valid arithmetic expression. If $Hello contained Hello + 1, bash would complain about the infinite recursion. – Stéphane Chazelas Jul 26 '17 at 15:28
  • Oh wow, I did not know that... So there’s an additional level of indirection! – Stephen Kitt Jul 26 '17 at 15:29
  • 1
    It's recursive. Also note that command substitutions may be run via that mechanism, so arithmetic evaluation upon uncontrolled data is a command injection vulnerability. – Stéphane Chazelas Jul 26 '17 at 15:30
  • 1
    It's more that when an arithmetic expression contains a variable name (including array members like a[2], and even (hence the ACE) a[`reboot`0]), then its content is evaluated as an arithmetic expression and the result substituted. But as a whole, it's different from using $var. For instance a=1+1; echo "$((a * 3)) $(($a * 3))" outputs 6 4. One can play with things like a=a=b++ b=1 bash -c 'echo "$((++a)) $b"' – Stéphane Chazelas Jul 26 '17 at 15:42
  • Note that in i=1+1; typeset -i i, the arithmetic expression is evaluated upon typeset in ksh93, zsh and mksh, but not in bash. – Stéphane Chazelas Jul 26 '17 at 16:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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