user2079828
user2079828

Reputation: 655

First Bash script problems with case statement

Just what it says. I'm trying to write a simple bash script from a question in a book. I'm trying to use the case statement, and for all I can tell I am using it correctly. However I keep getting "syntax error near unexpected token '$'in\r' case $i in.

No idea why. I'm also sure there are other problems in my code since this is my first script. The case statement is on line 10. Feel free to correct anything else, the end program will be building a grade data file for student grades, using a simple awk script to compute the average of the grades, and putting everything in the output file.

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

Upvotes: 0

Views: 1640

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 755094

If you write it as a loop, then you should probably write:

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
}

This fixes a number of problems:

  1. The test condition in the while loop.
  2. The non-obvious use of echo -n to suppress a newline plus the \n to add a newline.
  3. The indentation.
  4. The syntax of the checkLimits() function.
  5. The syntax of the condition in the checkLimits() function.
  6. Uninverts the inverted logic of the condition in the checkLimits() function.
  7. Actually decrements the variable i.

It does not fix the reliance on the global variable $i, which is pretty ugly.

The purpose of the loop must be to go back if there's an error and get the data reentered. That's a clever idea. Unfortunately, you never increment $i, so it doesn't really work.

Here is some working code:

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"

The output from a sample run:

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

Upvotes: 1

Related Questions