Bash脚本 - 如果语句不一致

时间:2017-10-03 18:37:31

标签: bash shell

我正在学习如何编写脚本,并且遇到了if语句的问题。该脚本读取用户输入的分数,并计算其平均成绩。但是,如果用户输入的分数低于0或大于100,则脚本应要求他们重新输入有效值。以下是代码:

#!/bin/bash

SCORE=0
AVERAGE=0
SUM=0
NUM=0

while true
do
    # Read score from user
    echo -n "Enter your score [0-100] ('q' for quit): "; read SCORE

    # Validate user input
    if (($SCORE < 0)) || (($SCORE > 100))
    then
        echo "Invalid input, try again: "
    #elif (( $SCORE == "q" )) 
    elif [ "$SCORE" == "q" ]
    then
        echo "Average rating: $AVERAGE%."
        break
    else
        # Perform calculation
        SUM=$[$SUM + $SCORE]
        NUM=$[$NUM +1]
        AVERAGE=$[$SUM / $NUM]
        echo "Average rating: $AVERAGE%"
    fi
done

注意我已将elif注释掉了。当我用[]表示法编写elif时,它按预期工作。但是,如果我切换到使用(())的elif,并输入&#34; 00&#34;作为我的分数,程序执行&#34;然后&#34;阻止和退出。它为什么这样做? 00不是&#39; q&#39;。

1 个答案:

答案 0 :(得分:5)

由于您建议的确切原因,行(( $SCORE == "q" ))不起作用。 ((..))仅用于算术运算,并且不能在其中执行字符串操作。您需要使用test运算符[[[

引用GNU bash文档

  

6.5 Shell算术

     

shell允许计算算术表达式,作为shell扩展之一,或使用((复合命令,let内置或-i选项来{{1} 1}}内置。

     

评估是在固定宽度的整数中完成的,没有检查溢出,但除以0被捕获并标记为错误。运算符及其优先级,关联性和值与declare语言中的相同。

与经典C运算符(test)一起使用时涉及字符串的一些标准表达式

[

您使用的Operator Syntax-Description ------------------------------------------------------------------------------------------- -z <STRING> True, if <STRING> is empty. -n <STRING> True, if <STRING> is not empty (this is the default operation). <STRING1> = <STRING2> True, if the strings are equal. <STRING1> != <STRING2> True, if the strings are not equal. 与使用[ "$SCORE" == "q" ]同义,只执行文字字符串匹配,但 [ "$SCORE" = "q" ]兼容后者。

POSIX比较运算符在双括号内的行为与单括号内的行为不同(文字和全局匹配)

==

此外,您可以使用遗留[[ $a == z* ]] # True if $a starts with an "z" (pattern matching). [[ $a == "z*" ]] # True if $a is equal to z* (literal matching). 运算符上的((..))运算符完全在算术上下文中重写您的语句。

$[ ... ]

请注意,我已将变量名称小写,以区别于环境变量(shell系统变量),但就像用户定义变量一样。并使用sum=$((sum + score)) ((num++)) (( num != 0 )) && average=$(( sum / num )) printf "%0.2f\n" $num 而不是printf来引入echo保证的POSIX不允许的浮点格式选项。