2

Currently working on my bash skills. I've done a few activites based on if/elif/else given to me to my tutor but can't put my finger on the one below.

Basically I'm tasked with outputting the following based on the input of a grade. Less than 40% = Fail 40% to 59% = Pass 60% to 69% = Merit 70% and above = Distinction

It seems to get caught on the first elif, presents the grade as merit for anything below 70 and doesn't check the others, it gives the same result when I change the order too.

echo "Please enter your grade"
read GRADE
echo

     if [ $GRADE -ge 70 ]; then
         echo "Well done, you got a distinction"

    elif [ $GRADE -ge 60 ] || [ $GRADE -le 69 ]; then
          echo "Well done, you got a merit"
    elif [ $GRADE -ge 40 ] || [ $GRADE -le 59 ]; then
          echo "Well done, you got a pass"
    else 
          echo "Unfortunately you failed"
      fi
4
  • 1
    Your statement uses || (logical OR), rather than && (logical AND). Commented Mar 28, 2017 at 19:08
  • Thank you! I knew it would be a basic syntax error and needed fresh eyes! Commented Mar 28, 2017 at 19:11
  • In fact, you can omit the [ $GRADE -le ... ] completely. The order of the the elifs already ensures that the grade is less than .... Commented Mar 28, 2017 at 19:12
  • Pretty much any number is either >= 60 or <=69. You have a logical error there. Commented Mar 28, 2017 at 21:02

4 Answers 4

1

A bit unusual solution

#bash 4.0+
while read -r -p 'Grade? (h-help)> ' grade
do
    case "$grade" in
        q) echo "quitting..." ; exit 0 ;;
        h) echo "Enter numeric value (0..100) or q for quit" ;&
        '') continue ;;
        *[!0-9]*) echo "Must be numeric value" ; continue ;;
    esac
    case 1 in
        $((grade > 100)) ) echo "impossible" ;;
        $((grade >= 70)) ) echo "distinction" ;;
        $((grade >= 60)) ) echo "merit" ;;
        $((grade >= 40)) ) echo "pass" ;;
                        *) echo "fail" ;;
    esac
done
Sign up to request clarification or add additional context in comments.

Comments

0

Your problem is in using || (or) rather than && (and). If you put in "10", 10 is LESS THAN 69 so it will drop into the first else.

Using set -x at the top of your script will help you figure this sort of thing out.

Comments

0

There better to use -a for AND and -o for OR in []. And do something like this:

if   [ $GRADE -lt 40 ]; then
    echo "Unfortunately you failed"
elif [ $GRADE -ge 40 -a $GRADE -lt 60 ]; then
    echo "Well done, you got a pass"
elif [ $GRADE -ge 60 -a $GRADE -lt 70 ]; then
    echo "Well done, you got a merit"
else
    echo "Well done, you got a distinction"

Comments

0

your problem came from the || (or), you need to use && (and). For exemple 65 is greater than 60 AND lesser than 69.

echo "Please enter your grade"
read GRADE
echo

 if [ $GRADE -ge 70 ]; then
     echo "Well done, you got a distinction"

elif [ $GRADE -ge 60 ] && [ $GRADE -le 69 ]; then
      echo "Well done, you got a merit"
elif [ $GRADE -ge 40 ] && [ $GRADE -le 59 ]; then
      echo "Well done, you got a pass"
else
      echo "Unfortunately you failed"
  fi

2 Comments

Lots of bugs still present than this. If the user enters -e . -o 1 as their grade, then they'll be told they got a distinction with no error, because the test invocations will look at whether . exists before they do any numeric comparisons at all. Quoting will cause such cases to (correctly) result in a failure with an error: if [ "$GRADE" -ge 70 ]
Moreover, all-caps variable names are used for variables with meaning to the OS or shell; names with at least one lowercase character are guaranteed not to conflict with names meaningful to POSIX-specified tools. See pubs.opengroup.org/onlinepubs/9699919799/basedefs/…, fourth paragraph.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.