【问题标题】:Bash scripting, multiple conditions in while loopBash脚本,while循环中的多个条件
【发布时间】:2013-03-10 04:47:22
【问题描述】:

我正在尝试在 bash 中使用两个条件的简单 while 循环,但是在尝试了各种论坛的许多不同语法之后,我无法停止抛出错误。这是我所拥有的:

while [ $stats -gt 300 ] -o [ $stats -eq 0 ]

我也试过了:

while [[ $stats -gt 300 ] || [ $stats -eq 0 ]]

... 以及其他几个构造。我希望这个循环在$stats is > 300$stats = 0 时继续。

【问题讨论】:

    标签: bash shell loops while-loop


    【解决方案1】:

    正确的选项是(按推荐的升序排列):

    # Single POSIX test command with -o operator (not recommended anymore).
    # Quotes strongly recommended to guard against empty or undefined variables.
    while [ "$stats" -gt 300 -o "$stats" -eq 0 ]
    
    # Two POSIX test commands joined in a list with ||.
    # Quotes strongly recommended to guard against empty or undefined variables.
    while [ "$stats" -gt 300 ] || [ "$stats" -eq 0 ]
    
    # Two bash conditional expressions joined in a list with ||.
    while [[ $stats -gt 300 ]] || [[ $stats -eq 0 ]]
    
    # A single bash conditional expression with the || operator.
    while [[ $stats -gt 300 || $stats -eq 0 ]]
    
    # Two bash arithmetic expressions joined in a list with ||.
    # $ optional, as a string can only be interpreted as a variable
    while (( stats > 300 )) || (( stats == 0 ))
    
    # And finally, a single bash arithmetic expression with the || operator.
    # $ optional, as a string can only be interpreted as a variable
    while (( stats > 300 || stats == 0 ))
    

    一些注意事项:

    1. [[ ... ]]((...)) 中引用参数扩展是可选的;如果未设置变量,-gt-eq 将假定值为 0。

    2. (( ... )) 中使用$ 是可选的,但使用它可以帮助避免意外错误。如果未设置stats,则(( stats > 300 )) 将假定stats == 0,但(( $stats > 300 )) 将产生语法错误。

    【讨论】:

    • 很棒的答案,非常彻底
    • 太棒了。回答帖子的经典方式。做得好。我假设您也可以使用与 until 相同的语法,是吗?
    • @SaxDaddy 或多或少,只要您注意正确否定条件:while [ foo -o bar ] 变为 until ! [ foo -o bar ],但 while foo || bar 变为 until ! foo && ! bar
    • 在读取传入数据时这似乎不起作用:while [[ read -r line && $inputdata != "" ]]; do。我该如何做到这一点?
    • 在读取传入数据时,例如,您可以将此表单用于多个条件:while read -r theline && [ "$theline" != "" ]
    【解决方案2】:

    试试:

    while [ $stats -gt 300 -o $stats -eq 0 ]
    

    [ 是对test 的调用。它不仅仅是用于分组,就像其他语言中的括号一样。查看man [man test 了解更多信息。

    【讨论】:

    • 我推荐[[ 而不是[。请参阅我对另一个答案的评论。
    • 这很公平。我使用 [ ] 因为那是 OP 试图使用的。我已经看到两者都成功使用了。
    【解决方案3】:

    第二种语法之外的额外 [ ] 是不必要的,并且可能会造成混淆。您可以使用它们,但如果必须,它们之间需要有空格。

    或者:

    while [ $stats -gt 300 ] || [ $stats -eq 0 ]
    

    【讨论】:

    • 实际上,[[ 通常是首选的内置来引入测试表达式。与旧的单一 [ 语法相比,它有几个优点。
    • @danfuzz 我知道这是一个旧线程,但如果你引用它会很棒,以防人们想了解为什么 [[ 比 [ 更受欢迎。我知道每个人都可以自己谷歌……但是,引用仍然是一个好习惯……使您的评论更加可靠,读者的搜索更快、更高效。
    猜你喜欢
    • 2014-10-30
    • 2015-04-04
    • 1970-01-01
    • 2019-12-10
    • 2023-04-06
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多