超出表达式递归级别

Expression recursion level exceeded

不知道为什么下面的例子有错误:

$ 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")
$ 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;不要混合类型。

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