超出表达式递归级别
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")
这就是为什么这种情况很少发生。如果您在已经处于算术上下文中时进行赋值,那么右侧不能解析为 除了 整数以外的任何东西。不会发生递归。所以要么
- 在
(( ))
里面做所有事情。 (你也可以在那里做作业。)
- 首先使用
declare -i
;不要混合类型。
当您在算术表达式中使用变量,但值不是数字时,shell 将其视为另一个表达式来计算。因此,如果该值是一个变量名,它将获取该变量的值并使用它。但在这种情况下,你让它指向自己。所以要评估 a
它必须评估 a
,并且这会无限重复。
不知道为什么下面的例子有错误:
$ 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")
这就是为什么这种情况很少发生。如果您在已经处于算术上下文中时进行赋值,那么右侧不能解析为 除了 整数以外的任何东西。不会发生递归。所以要么
- 在
(( ))
里面做所有事情。 (你也可以在那里做作业。) - 首先使用
declare -i
;不要混合类型。
当您在算术表达式中使用变量,但值不是数字时,shell 将其视为另一个表达式来计算。因此,如果该值是一个变量名,它将获取该变量的值并使用它。但在这种情况下,你让它指向自己。所以要评估 a
它必须评估 a
,并且这会无限重复。