【问题标题】:Expression recursion level exceeded error in BashBash 中的表达式递归级别超出错误
【发布时间】:2019-03-16 03:26:29
【问题描述】:

我是 bash 脚本和尝试做一些练习的新手。当我试图用“finish”字符串停止程序时出现这样的错误。:

line 9: ((: finish: expression recursion level exceeded (error token is "finish").

有什么问题?我也想了解我的其他缺点。 我的程序是:

#!/bin/bash
number=0
finish="finish"
temp=0
echo "Enter a number."
while true;
do
    read -r number
    if (( $number > $temp ))
    then
        temp=$number
    fi
    if [[ $number == $finish ]]
    then 
       break
    fi
done    
echo "Largest : $temp"  

【问题讨论】:

    标签: bash if-statement syntax arithmetic-expressions


    【解决方案1】:

    引用@barmar's great answer 的相关问题,该问题涉及@GordonDavisson 在他的评论中提到的同一问题:

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


    最简单的解决方案是为您的变量使用不同的名称 - 例如 finish_string="finish" 而不是 finish="finish"

    此外,您可以使用正则表达式匹配来查看值是否为数字(注意:在算术表达式((...)) 中扩展变量不需要美元符号),然后进行数字比较,然后进行普通字符串比较查看该值是否为“完成”:

    if [[ $number =~ ^[0-9]+$ ]] && ((number > temp)); then
      temp=$number
    elif [[ $number == $finish ]]; then
      break
    fi
    

    或者,您可以在进行数字比较之前明确检查用户是否输入了数字:

    if [[ $number == $finish ]]; then
      break
    else
      [[ $number =~ ^[0-9]+$ ]] || { echo "Enter a valid number or 'finish' to stop"; continue; }
      if ((number > temp)); then
        temp=$number
      fi
    fi
    

    使用bash -x yourscript.sh 运行您的脚本以对其进行调试。


    相关:

    另见:

    【讨论】:

    • 更具体地说:最初的问题是当它在算术表达式中看到$number 时,它会将其扩展为变量的值:“finish”。这不是一个数字,所以它与表达式中的非数字所做的一样:假设它们是隐式引用的变量并扩展它们。在这种情况下,将finish 扩展为变量会产生“完成”,这也不是数字,因此它会尝试将其扩展为变量......等等等等,直到它决定尝试足够长的时间并放弃。
    • 惊人的解释@GordonDavisson。我不知道这个问题。
    • @codeforester 感谢您的回答,我明白了。然而,在第一个解决方案中,临时变量在我将整数分配给数字变量后不会改变。程序给出的解决方案总是 0,在第二个解决方案中它给出了与我的相同的错误。
    • 我的正则表达式模式是错误的,这就是代码没有做它应该做的事情的原因。我现在已经解决了这个问题。
    【解决方案2】:

    “finish”不是一个数字,但您正在将它与一个数字进行比较。要解决您的直接问题,请在进行比较之前检查“finish”:

    while true;
    do
        read -r number
        if [[ $number == $finish ]] ## this line moved up
        then 
           break
        fi
        if (( $number > $temp ))
        then
            temp=$number
        fi
    done 
    

    当然,你还有一个问题,即使 $number != "finish",它可能仍然不是一个数字,但这不是问题...

    【讨论】:

    • 这会很好用,虽然不是很优雅。如果 ((...)) 中使用的变量扩展为非数字值,则算术表达式的计算结果为 false。
    • @codeforester 你是对的,当然。但是,不检查输入有效性似乎与问题所涉及的错误不同。解决这个问题,我们可能最终会为他编写代码......
    猜你喜欢
    • 2015-06-25
    • 2015-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 2016-12-10
    • 2020-04-20
    相关资源
    最近更新 更多