超出表达式递归级别

时间:2015-05-22 19:51:15

标签: bash arithmetic-expressions

不知道为什么以下示例中存在错误:

$ a=1; (( a > 0 )) && echo y || echo n
y
$ a=x; (( a > 0 )) && echo y || echo n
n
$ a=a; (( a > 0 )) && echo y || echo n
-bash: ((: a: expression recursion level exceeded (error token is "a")
n

2 个答案:

答案 0 :(得分:7)

$ a=a
( no error )
$ declare -i a
$ a=a
-bash: ((: a: expression recursion level exceeded (error token is "a")

这种行为是因为declare -i将赋值的RHS放在算术上下文中。在算术上下文中,bash以递归方式将变量名称解引用到它们的值。如果名称取消引用,则会发生无限递归。

为了进一步说明,如果在在该名称上设置整数属性之前将相关变量分配给与变量名称​​相同的字符串,则只会出现此行为。

$ unset a
$ declare -i a
$ a=a
( This is fine, $a dereferences to 0. )
$ unset a
$ a=a
$ declare -i a
$ a=a
-bash: ((: a: expression recursion level exceeded (error token is "a")

这就是为什么这种情况很少发生的原因。如果在已经处于算术上下文中的情况下执行赋值,则右侧无法解析为整数之外的任何内容。不会发生递归。所以要么

  1. (( ))内执行所有操作。 (你也可以在那里做作业。)
  2. 首先使用declare -i;不要混合类型。

答案 1 :(得分:5)

在算术表达式中使用变量但值不是数字时,shell会将其视为要评估的另一个表达式。因此,如果值是变量名,它将获取该变量的值并使用它。但在这种情况下,你有它指向自己。因此,要评估a,必须评估a,这会不断重复。