Hi,
I'm just learning so I would appreciate some understanding line by line on the while loop/case script below.
Thanks so much.
joe.
echo "Good Morning."
echo "Enter 1 to Add"
echo "or q to quit."
while [ "$Enter" != "q" ]
do
read Enter
case $Enter in
1) echo "Addtion:"
echo "Enter a number"
read num1
echo "Enter another number"
read num2
sum=$((num1 + num2))
echo "sum=$sum."
;;
q) exit;;
esac
echo "Enter another or q to quit"
done
Line 1 - good morning.
Line 2 - Enter option 1 to add.
Line 3 - option q to quit.
Line 4 - "while (loop) - Whatever is entered is not equal to q or quit.
Line 5 - do (part of while loop) - read "Enter" ? (not sure)
Line 6 - "case" - Whatever is entered, is input?? (also not sure)
The rest I understand. The punch line is that sum=$((num1 + num2)) will perform the general addition.
And the sum, sum= echo "$sum" will be sent to standard output.
Yes and no. I think you are missing the point, though. Programs are read like onions, peeling layers of loops off. Anyway, the script is poorly written and you should understand that, as we go along. A big part of programming is to imagine what could happen and proactively deal with it. Not logic, but foresight:
echo "Good Morning."
echo "Enter 1 to Add"
echo "or q to quit."
Just Output, not interesting.
while [ "$Enter" != "q" ]
do
....
done
Now this is more interesting: This loop (and everything inside) is executed over and over again, as long as the condition is true: "$Enter" is not equal "q". Lets see what this "everything inside" is:
read Enter
case $Enter in
1) echo "Addtion:"
echo "Enter a number"
read num1
echo "Enter another number"
read num2
sum=$((num1 + num2))
echo "sum=$sum."
;;
q) exit;;
esac
First some input is read from the keyboard. Then the "case .. esac" starts. This basically has a branch, which is executed when variable "Enter" has a cerain value:
case $Enter in <= compare the content of $Enter to:
1) echo "Addtion:" <= if it is "1", do this
echo "Enter a number"
read num1
echo "Enter another number"
read num2
sum=$((num1 + num2))
echo "sum=$sum."
;; <= until here (";;")
q) exit;; <= if it is "q", do this until ";;"
esac
Now, why is this script poorly written: first, you ask the user to do something, which is fine. But you use some code the first time and other code for all subsequent executions of the while-loop! You should move this output into the loop so that it is executed every time, not only the first time, then you can skip the last "echo":
echo "Good Morning."
while [ "$Enter" != "q" ]
do
echo "Enter 1 to Add"
echo "or q to quit."
read Enter
case $Enter in
1) echo "Addtion:"
echo "Enter a number"
read num1
echo "Enter another number"
read num2
sum=$((num1 + num2))
echo "sum=$sum."
;;
q) exit;;
esac
done
Second, you deal with "Enter" being "q" and "1", but what do you do if neither is entered? You should at least tell the user that you can't understand what he wants. Let us enter another branch for this, which deals with all other values, which are neither "1" nor "q":
echo "Good Morning."
while [ "$Enter" != "q" ]
do
echo "Enter 1 to Add"
echo "or q to quit."
read Enter
case $Enter in
1)
echo "Addtion:"
echo "Enter a number"
read num1
echo "Enter another number"
read num2
sum=$((num1 + num2))
echo "sum=$sum."
;;
q)
exit
;;
*)
echo "Enter only q or 1, nothing else."
;;
esac
done
Third: if you ask the user to enter "q" to quit you may want to allow "Q" as well. Some users have the CapsLock-key turned on without noticing, some are simply conviced that Caps work better.
echo "Good Morning."
while [ "$Enter" != "q" ]
do
echo "Enter 1 to Add"
echo "or q to quit."
read Enter
case $Enter in
1)
echo "Addtion:"
echo "Enter a number"
read num1
echo "Enter another number"
read num2
sum=$((num1 + num2))
echo "sum=$sum."
;;
[qQ])
exit
;;
*)
echo "Enter only q or 1, nothing else."
;;
esac
done
Now the "exit" is executed if "$Enter" either holds "q" or "Q".
Fourth: you take the variable "Enter" (and the others) for granted, but it isn't (and they aren't). It is good style to declare what you use before you use it. This also allows to comment on the usage of a variable so that the maintainer of the program can more easily change it should the need arise. In addition a declaration will make sure that the variable has the expected scope, once you start using functions and procedures. It is never too early to start developing good habits.
Speaking of good habits: always use a "shebang" in the first line, so your script will be executed by the shell of your choice, not by the one the user happens to use:
#! /usr/bin/ksh
typeset Enter="" # user input buffer
typeset -i num1=0 # addition operands
typeset -i num2=0 # -"-
typeset -i sum=0 # addition result
echo "Good Morning."
while [ "$Enter" != "q" ]
do
echo "Enter 1 to Add"
echo "or q to quit."
read Enter
case $Enter in
1)
echo "Addtion:"
echo "Enter a number"
read num1
echo "Enter another number"
read num2
sum=$((num1 + num2))
echo "sum=$sum."
;;
[qQ])
exit
;;
*)
echo "Enter only q or 1, nothing else."
;;
esac
done
Lastly, now that we have covered all the possible inputs in the case..esac we do not need the exit-condition for the while-loop any more. We can change it to an endless loop:
#! /usr/bin/ksh
typeset Enter="" # user input buffer
typeset -i num1=0 # addition operands
typeset -i num2=0 # -"-
typeset -i sum=0 # addition result
echo "Good Morning."
while : ; do
echo "Enter 1 to Add"
echo "or q to quit."
read Enter
case $Enter in
1)
echo "Addtion:"
echo "Enter a number"
read num1
echo "Enter another number"
read num2
sum=$((num1 + num2))
echo "sum=$sum."
;;
[qQ])
exit
;;
*)
echo "Enter only q or 1, nothing else."
;;
esac
done