Script reading needed

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 

Now its indented, is it not more clear?
You tell us what you read and we will correct...

Thanks so much. Okay.

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.

esac completes "case."
done completes "while" loop.

Hope I'm close.

Thanks again,
joe.

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. :wink:

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

I hope this helps.

bakunin