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.