-2

When the script asks me for input, I get an error if I just press Return without typing in anything. How do I fix this?

Here's the script:

 #!/bin/bash

   SUM=0
   NUM=0

   while true
   do echo -n "Pruefungspunkte eingeben ('q' zum Beenden): "
      read SCORE
      if test "$SCORE" == "q"
      then echo "Durchschnittspunktzahl: $AVERAGE."
           break
      else SUM=`expr $SUM + $SCORE`
           NUM=`expr $NUM + 1`
           AVERAGE=`expr $SUM / $NUM`
      fi
   done
6
  • 1
    What error in particular? Commented Jun 15, 2013 at 11:45
  • I can't tell, someone asked me to fix this Commented Jun 15, 2013 at 11:47
  • @user2488736 You could at least copy the content into a file, execute the use case you described and tell us which error is generated.
    – Matteo
    Commented Jun 15, 2013 at 11:48
  • 1
    Aha, someone asked you to fix it, then you asked someone else and so on. I bet that someone is not an original author of question either. Commented Jun 15, 2013 at 11:50
  • Whats wrong with asking someone for help if you can't find a solution, I'm a total newb sry Commented Jun 15, 2013 at 11:54

3 Answers 3

3

How about using good bash practices?

#!/bin/bash

sum=0
num=0

while true; do
   read -erp "Pruefungspunkte eingeben ('q' zum Beenden): " score
   if [[ $score = q ]]; then
      echo "Durchschnittspunktzahl: $average."
      break
   elif [[ $score =~ ^-?[[:digit:]]+$ ]]; then
      ((sum+=10#$score))
      ((++num))
      ((average=sum/num))
   else
      echo "Bad number"
   fi
done

Good practice:

  • don't use capitalized variable names
  • use the [[ builtin instead of the test builtin
  • don't use backticks, use (( to invoke shell arithmetic
  • to make sure the user inputs a number, check that a number was really entered. The line

    elif [[ $score =~ ^-?[[:digit:]]+$ ]]; then
    

    just does that (see regular expressions). Incidentally it completely solves your original problem, since an empty input will not pass through this test

  • to prevent problems if a user enters 09 instead of 9, force bash to interpret the input in radix 10. That's why I'm using (10#$score) instead of just score.
  • Use read with the -p (prompt) option, instead of the clumsy combo echo -n / read

This version is much more robust and well-written than yours. Yet, it still has problems:

  • will break if user needs large numbers
  • as shell arithmetic is used, only integers can be used. Moreover, the average given by this program is rounded: if you want the average of 1 and 2 you'll have 1.

To fix both problems, you'll probably want to use bc or dc. But that will be the purpose of another question. Or not.

4
  • Please, quote the variable "$score". If user's input has a space, you will fail on [[ $score ... ]] expansion.
    – bartimar
    Commented Jun 15, 2013 at 13:27
  • 2
    @bartimar, according to Bash manual (and personal experience), "word splitting ... are not performed on the words between the �?[[’ and �?]]’ ..."
    – doubleDown
    Commented Jun 15, 2013 at 13:43
  • 1
    @bartimar thanks for your comment. $score need not be quoted inside [[ (see doubleDown's comment above). That's one reason why I mentioned using [[ instead of test (see good practice point 2). And thanks for downvoting. Commented Jun 15, 2013 at 14:21
  • Oh, I'm sorry... I lived in a lie! I think it will expand first and the space will be a problem. My apologies for the down, can you edit it so i can up? :/
    – bartimar
    Commented Jun 15, 2013 at 15:00
1

Initialise $SCORE beforehand or handle empty input like you do in q case.

1
[[ -z "$SCORE" ]] && echo "\$SCORE is zero, e.g. \"\"" 

This will test if the variable SCORE is empty string.

You should also set AVERAGE=0 at the beginning.

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.