【问题标题】:First Bash script problems with case statement案例语句的第一个 Bash 脚本问题
【发布时间】:2013-10-29 02:58:04
【问题描述】:

正如它所说的那样。我正在尝试根据书中的问题编写一个简单的 bash 脚本。我正在尝试使用 case 语句,并且据我所知,我正在正确使用它。但是,我不断收到“意外令牌'$'in\r' case $i in 附近的语法错误。

不知道为什么。我也确定我的代码中还有其他问题,因为这是我的第一个脚本。 case 语句在第 10 行。随意更正任何其他内容,最终程序将为学生成绩构建一个成绩数据文件,使用简单的 awk 脚本计算成绩的平均值,并将所有内容放入输出文件中。

function getStudentData () { 
    i=0
    while [ $i<5 ]
    do
        case $i in
           [0]) echo -n "Enter student name\n"
              read name
              ;;
           [1]) echo -n "Enter Quiz grade\n" 
                read quiz
                checkLimits $quiz
                ;;
           [2]) echo -n "Enter homework grade\n"
                read hw
                checkLimits $hw
                ;;
            [3]) echo -n "Enter midterm grade\n"
                 read midterm
                 checkLimits $midterm
                  ;;
           [4]) echo -n "Enter Final grade \n"
                read final
                checkLimits $final
                ;;
        esac
done
}

function checkLimits ($grade) {
if [ grade <= 100 || grade >= 0 ]; then
    $i--
fi
}

if [ $# -lt 2 ]; then
echo "Incorrect number of arguments"
exit 1
fi

#Check awk existance
if [ ! -e $2 ]; then
echo "Error, .awk file does not exist"
exit 1
fi

#flag for data file existing, and awk file
flag=0

#Check for data file existing
if [ ! -e $1 ];then
flag=0
else
flag=1
fi
ans="yes"
while [ $ans == "yes" || $ans == "y" ]
do
echo "Do you want to enter a student record?"
read ans

if [ $ans == "y" || $ans == "yes" ];then
    getStudentData 

else
    echo "we done"
    exit 1
fi
done

【问题讨论】:

  • [ $i&lt;5 ] 并没有像你想象的那样做。
  • 是否需要 while (( $i
  • 这行得通,是的,但您需要了解原因。尝试检查 [bash 的手册页。
  • 实际上,这只是在第 6 行创建了一个意外标记:while (( $i
  • 你确定你是用bash而不是/bin/sh来运行这个吗?

标签: bash


【解决方案1】:

如果你把它写成一个循环,那么你可能应该这样写:

function getStudentData () { 
    i=0
    while [[ $i < 5 ]]
    do
        case $i in
           0) echo -n "Enter student name: "
              read name
              ;;
           1) echo -n "Enter Quiz grade: " 
              read quiz
              checkLimits $quiz
              ;;
           2) echo -n "Enter homework grade: "
              read hw
              checkLimits $hw
              ;;
           3) echo -n "Enter midterm grade: "
              read midterm
              checkLimits $midterm
              ;;
           4) echo -n "Enter Final grade: "
              read final
              checkLimits $final
              ;;
        esac
    done
}

function checkLimits() {
    if [[ $1 -gt 100 || $1 -lt 0 ]]
    then ((i--))
    fi
}

这解决了一些问题:

  1. while 循环中的测试条件。
  2. 不明显地使用 echo -n 来禁止换行加上 \n 来添加换行。
  3. 缩进。
  4. checkLimits() 函数的语法。
  5. checkLimits() 函数中条件的语法。
  6. 取消反转 checkLimits() 函数中条件的反转逻辑。
  7. 实际上是递减变量i

它没有修复对全局变量$i的依赖,这很丑。

循环的目的必须是在出现错误时返回并重新输入数据。这是一个聪明的主意。不幸的是,您永远不会增加 $i,因此它实际上不起作用。

这是一些工作代码:

function getStudentData () { 
    for ((i = 0; i < 5; i++))
    do
        case $i in
           0) echo -n "Enter student name: "
              read name
              ;;
           1) echo -n "Enter Quiz grade: " 
              read quiz
              checkLimits $quiz
              ;;
           2) echo -n "Enter homework grade: "
              read hw
              checkLimits $hw
              ;;
           3) echo -n "Enter midterm grade: "
              read midterm
              checkLimits $midterm
              ;;
           4) echo -n "Enter Final grade: "
              read final
              checkLimits $final
              ;;
        esac
    done
}

function checkLimits() {
    if [[ $1 -gt 100 || $1 -lt 0 ]]
    then ((i--))
    fi
}

getStudentData
echo "Name     = $name"
echo "Quiz     = $quiz"
echo "Homework = $hw"
echo "Midterm  = $midterm"
echo "Final    = $final"

样本运行的输出:

Enter student name: Eileen
Enter Quiz grade: 92
Enter homework grade: 94
Enter midterm grade: 95
Enter Final grade: 97
Name     = Eileen
Quiz     = 92
Homework = 94
Midterm  = 95
Final    = 97

【讨论】:

  • 我完全同意你所说的,我知道我还没有增加任何东西。我的其他代码一定有问题。我删除了所有代码,并将此代码放入一个 .sh 文件中,然后使用 sh name.sh 运行它。在第 3 行: for (( i = 0; i
  • 你有 DOS 行尾;它抱怨 CRLF 行尾中的 CR。如果您想要 DOS,请使用 Windows 机器。如果您想要bash,请使用 Unix 机器并确保使用 Unix 行尾。另见:How to convert DOS/Windows newline to Unix newline in bash script?
  • 啊,我正在从 Windows 环境中学习并在远程系统上运行。所以基本上我所有的行都以 \n 结尾,而它们需要以 \r 结尾?或者,也许我是误会了。我一两周前写了一个awk脚本,没有出现这个问题。
  • 否;你的行结束\r\n,需要结束\n。找到dos2unixdtou 命令,或使用tr 或使用vim:set fileformat=unix
  • 太棒了,我想知道为什么当我没有类似的东西时它一直提到 $\r。所以我猜它错误地解释了回车,只需要一个换行符。我必须记住这一点。谢谢你的帮助,我已经修好了。
猜你喜欢
  • 2019-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-21
  • 2015-09-16
  • 1970-01-01
相关资源
最近更新 更多