Search code examples
basharithmetic-expressions

Expression recursion level exceeded


Don't know why there is error in the following examples:

$ 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")

Solution

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

    This behavior is because declare -i puts the right-hand side of an assignment in arithmetic context. In arithmetic context, bash dereferences variable names to their values recursively. If the name dereferences to itself, infinite recursion ensues.

    To clarify further, you would only get this behavior if the variable in question was assigned to a string identical to the name of the variable before setting the integer attribute on that name.

    $ 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")
    

    That's why this is a rare occurrence. If you do the assignment when you're already in arithmetic context, then the right-hand side cannot resolve to anything other than an integer. No recursion can occur. So either

    1. Do everything inside (( )). (You can do assignments in there, too.)
    2. Use declare -i first thing; don't mix types.