Shell programming and simple menus - part 2

Unix Insider –

In last month's column we started a simple menu system, as useful utility that illustrated several shell programming concepts. Now let's take that a step further. In the next example, the menu system is broken into two parts: the shell script that executes the menu, and a separate "data" file that contains the menu prompts and commands to be executed.

Listing 2 looks very similar to the first menu in last month's Listing 1 (see sidebar) except that it is missing all of the menu prompts and commands to execute! Where are they?

Listing 3 is an example of a menu file to be processed by

<font face="Courier">shellmenu</font>
. This file contains the missing information. You have to study both listings to see how these work together. Both listings include line numbers to simplify the explanations.

If you compare last months Listing 1 to Listing 2 and Listing 3 from this month, you will see that these two listings are almost identical, but the prompts and function definitions have been split out of Listing 2 and placed in Listing 3.

The key points to look at in Listing 2 are "TEST THE COMMAND LINE" at lines 68 through 80, "TEST THE MENU FILE" at lines 81 through 100 and "READ THE MENU FILE" at lines 132 through 138.

Be sure that

<font face="Courier">shellmenu</font>
has been given execute privileges with the command:

<font face="Courier">chmod a+x shellmenu</font>

To start this menu using the file named

<font face="Courier">mf.mnu</font>
shown in Listing 3 as the menu, type the
<font face="Courier">shellmenu</font>
command followed by the name of the file to use as the menu.

<font face="Courier">shellmenu</font>
<font face="Courier">mf.mnu</font>

This causes the value

<font face="Courier">mf.mnu</font>
to be assigned to a variable, $1, inside the shell script. The variables $0, $1, $2, $3 and so on exist in all shell scripts and contain any values that were listed on the command line that was used to start the script. $0 contains the name of the shell script itself,
<font face="Courier">shellmenu</font>
. $1 contains the first word on the command line after
<font face="Courier">shellmenu</font>
, in this case
<font face="Courier">mf.mnu</font>
. The $2 variable would contain the next word or argument on the command line after
<font face="Courier">mf.mnu</font>
if there were any. The shell also creates a variable named $#. This variable contains the number of arguments that were on the command line after the command (in this case,
<font face="Courier">shellmenu</font>
).

For the command:

<font face="Courier">shellmenu</font>
<font face="Courier">mf.mnu</font>
the $# variable should contain the value 1 for the 1 argument on the command line.

In "TEST THE COMMAND LINE" at line 75 through 79, the value of $# is tested, and if it is not 1 then a usage message is displayed and the script exits. The syntax for the test is

<font face="Courier">if [ ! $# = 1 ]
then
    usage
    exit
fi
</font>

Carefully copy the spacing used in the command there are spaces around the left bracket and the right bracket. The "!" means NOT in this test. The test reads "if the number of arguments is not 1 then execute a

<font face="Courier">usage()</font>
function and exit the script."

The

<font face="Courier">usage()</font>
function is defined at lines 10 through 20 and attempts to describe the correct usage for the
<font face="Courier">shellmenu</font>
script.

In "TEST THE MENU FILE", at line 87, a new variable, $MENU, is created and is assigned the value of $1. Another test is done to determine if the file exists and is readable. The test:

<font face="Courier">if [ -r $MENU ]</font>

uses the name of the file in $MENU,

<font face="Courier">mf.mnu,</font>
and then tests two conditions. The -r tests that the file exists and that it is readable. If so it returns "true" logically. We want the opposite test, so a NOT (!) is added in:

<font face="Courier">if [ ! -r $MENU ]</font>

Again notice spaces around the left and right brackets.

This tests if the file

<font face="Courier">mf.mnu</font>
exists and is readable, provides a message for the user, and displays the usage information and exits.

Finally the trick as to how the this menu system works appears in "READ THE MENU FILE" at line 87. Note the period in the command:

<font face="Courier">. $MENU </font>

The period is a special character in a shell script that basically says read the following named file (or the file named in the variable) on this line as if it were part of this current script. It acts very much like a "include" or "copy" directive. As the file is included, the commands in it are executed.

Listing 2: Sample shell script menu driver

1. #!/bin/sh
2. # shellmenu
3. # Simple shell script menu driver under UNIX
4. # Main logic starts at MAIN LOGIC
5.  
6. #---------------------------------------
7. # FUNCTION DEFINITIONS
8. #---------------------------------------
9.  
10. # A function for usage info
11. usage () {
12. echo "Usage: shellmenu menu_file"
13. echo "  A menu file must contain 12 variables"
14. echo "  amenu through l menu"
15. echo "  defining the prompts for a menu"
16. echo "  and the definitions for 12"
17. echo "  functions apick() through lpick()"
18. echo "  that define the commands to be"
19. echo "  executed for each of the 12 picks"
20. }
21. # Define a function for invalid menu picks
22. # The function loads an error message into a variable
23. badchoice ()
24. {
25. MSG="Invalid Selection ... Please Try Again" ;
26. }
27. 
28. #---------------------------------------
29. # DISPLAY FUNCTION DEFINITION
30. #---------------------------------------
31. # This function displays the menu.
32. # The routine clears the screen, echoes
33. # the logo and menu prompts
34. # and some additional messages.
35. # Note that this definition does
36. # not cause the function to
37. # be executed yet, it just defines
38. # it ready to be executed.
39.  
40. displaymenu () {
41. # clear the screen
42. clear
43. echo `date`
44. echo
45. echo "\t\t\t" $LOGO
46. echo
47. echo "\t\tPlease Select:"
48. echo
49. echo "\t\t\t" $amenu
50. echo "\t\t\t" $bmenu
51. echo "\t\t\t" $cmenu
52. echo "\t\t\t" $dmenu
53. echo "\t\t\t" $emenu
54. echo "\t\t\t" $fmenu
55. echo "\t\t\t" $gmenu
56. echo "\t\t\t" $hmenu
57. echo "\t\t\t" $imenu
58. echo "\t\t\t" $jmenu
59. echo "\t\t\t" $kmenu
60. echo "\t\t\t" $lmenu
61. echo "\t\t\tx. Exit"
62. echo
63. echo $MSG
64. echo
65. echo Select by pressing the letter and then ENTER ;
66. }
67.  
68. #---------------------------------------
69. # TEST THE COMMAND LINE
70. #---------------------------------------
71. # There should only be one argument
72. # on the command line, which 
73. # should be the name of a menu file
74.  
75. if [ ! $# = 1 ]
76. then
77.     usage
78.     exit
79. fi
80.  
81. #---------------------------------------
82. # TEST THE MENU FILE
83. #---------------------------------------
84. # Assign the value of the first argument
85. # on the command line,
86.  
87. MENU=$1
88.  
89. # Test that the file exists and is readable.
90. # Abort if it is not
91.  
92. if [ ! -r $MENU ]
93. then
94.     echo "Can't locate or read " $MENU
95.     echo "Press ENTER to acknowledge."
96.     read $answer
97.     usage
98.     exit
99. fi
100.  
101. #---------------------------------------
102. # MAIN LOGIC
103. #---------------------------------------
104. # Clear out the error message
105. MSG=
106.  
107. #---------------------------------------
108. # MAIN LOOP
109. #---------------------------------------
110. # We're here because we have a file
111. # that can be read, so OK to
112. # continue with the main loop of the menu.
113.  
114. # Repeat the menu over and over
115. # Steps are:
116. # 1. Display the menu
117. # 2. 'read' a line of input from the keyboard
118. # 3. Clear the error message
119. # 4. Check the answer for a or A or b or B, etc. and dispatch
120. #    to the appropriate program or function or exit
121. # 5. If the entry was invalid call the
122. #     badchoice() function
123. #    to initialize MSG to an error message
124. # 6. This error message is used when setting
125. #    up the menu for a menu pick that is
126. #    valid but has no command
127. #    associated with it.
128. 
129. while  true
130. do
131.  
132. #---------------------------------------
133. # READ THE MENU FILE
134. # define the menu by reading in the file
135. # named on the command line
136. #---------------------------------------
137.     . $MENU
138.  
139. #---------------------------------------
140. # DISPLAY THE MENU
141. # and read the user pick
142. #---------------------------------------
143.     displaymenu
144.     read answer
145.     MSG=
146. # dispatch to the users selection
147.     case $answer in
148.         a|A) apick;;
149.         b|B) bpick;;
150.         c|C) cpick;;
151.         d|D) dpick;;
152.         e|E) epick;;
153.         f|F) fpick;;
154.         g|G) gpick;;
155.         h|H) hpick;;
156.         i|I) ipick;;
157.         j|J) jpick;;
158.         k|K) kpick;;
159.         l|L) lpick;;
160.         x|X) break;;
161.         *) badchoice;;
162.     esac
163. done
164.  <<<
<font face="Courier">End of Listing</font>
>>>

Listing 3:

<font face="Courier">mf.mnu</font>
-- a file of menu prompts and picks

1. # mf.mnu a simple script menu for shellmenu
2. # This file is read directly into shellmenu
3. # using the dot (.) prefix as in
4. #       
<font face="Courier">shellmenu</font>
this_file 5. # 6. # causing the contents 7. # of this file to be read as part of the shell script 8. 9. # The logo for this menu will be displayed 10. # at the top of the screen 11. LOGO="More Functions" 12. 13. # Here are the list of menu prompts and the 14. # commands that go with them 15. # In the first list, enter the menu prompt 16. # as it should appear 17. # on the menu for each of the letters A - L 18. # In the second list, replace badchoice 19. # with any commands to run 20. # when that letter is pressed. 21. 22. #--------------------------------------- 23. # MENU PROMPTS 24. #--------------------------------------- 25. amenu="a. Job Scheduling" ; 26. bmenu="b. Set Standard Defaults " ; 27. cmenu="c. Display Directory Listing " ; 28. dmenu="d Other Functions" ; 29. emenu=" " ; 30. fmenu=" " ; 31. gmenu=" " ; 32. hmenu=" " ; 33. imenu=" " ; 34. jmenu=" " ; 35. kmenu=" " ; 36. lmenu=" " ; 37. 38. #--------------------------------------- 39. # MENU ACTIONS AND COMMANDS 40. #--------------------------------------- 41. apick () { shmnu ; } 42. bpick () { defmnt ; } 43. cpick () 44. { 45. ls -l| more ; echo Press Enter ; read DUMMY ; 46. } 47. dpick () {
<font face="Courier">shellmenu</font>
sf.mnu ; } 48. epick () { badchoice ; } 49. fpick () { badchoice ; } 50. gpick () { badchoice ; } 51. hpick () { badchoice ; } 52. ipick () { badchoice ; } 53. jpick () { badchoice ; } 54. kpick () { badchoice ; } 55. lpick () { badchoice ; } 56. <<<
<font face="Courier">End of Listing</font>
>>>

Putting it all together

Listing 4 is a logical representation of combination of

<font face="Courier">shellmenu</font>
including the
<font face="Courier">. $MENU</font>
command. Once you look at the combination, there is little difference between the original Listing 1 last month and Listing 4.

Listing 4: The logical combination of

<font face="Courier">shellmenu</font>
and
<font face="Courier">mf.mnu</font>

1. #!/bin/sh
2. # 
<font face="Courier">shellmenu</font>
3. # Simple shell script menu driver under UNIX 4. # Main logic starts at MAIN LOGIC 5. 6. #--------------------------------------- 7. # FUNCTION DEFINITIONS 8. #--------------------------------------- 9. 10. # A function for usage info 11. usage () { 12. echo "Usage:
<font face="Courier">shellmenu</font>
menu_file" 13. echo " A menu file must contain 12 variables" 14. echo " amenu through l menu" 15. echo " defining the prompts for a menu" 16. echo " and the definitions for 12" 17. echo " functions apick() through lpick()" 18. echo " that define the commands to be" 19. echo " executed for each of the 12 picks" 20. } 21. # Define a function for invalid menu picks 22. # The function loads an error message into a variable 23. badchoice () 24. { 25. MSG="Invalid Selection ... Please Try Again" ; 26. } 27. 28. #--------------------------------------- 29. # DISPLAY FUNCTION DEFINITION 30. #--------------------------------------- 31. # This function displays the menu. 32. # The routine clears the screen, echoes 33. # the logo and menu prompts 34. # and some additional messages. 35. # Note that this definition does 36. # not cause the function to 37. # be executed yet. It just defines 38. # it as ready to be executed. 39. 40. displaymenu () { 41. # clear the screen 42. clear 43. echo `date` 44. echo 45. echo "\t\t\t" $LOGO 46. echo 47. echo "\t\tPlease Select:" 48. echo 49. echo "\t\t\t" $amenu 50. echo "\t\t\t" $bmenu 51. echo "\t\t\t" $cmenu 52. echo "\t\t\t" $dmenu 53. echo "\t\t\t" $emenu 54. echo "\t\t\t" $fmenu 55. echo "\t\t\t" $gmenu 56. echo "\t\t\t" $hmenu 57. echo "\t\t\t" $imenu 58. echo "\t\t\t" $jmenu 59. echo "\t\t\t" $kmenu 60. echo "\t\t\t" $lmenu 61. echo "\t\t\tx. Exit" 62. echo 63. echo $MSG 64. echo 65. echo Select by pressing the letter and then ENTER ; 66. } 67. 68. #--------------------------------------- 69. # TEST THE COMMAND LINE 70. #--------------------------------------- 71. # There should be only one argument 72. # on the command line, which 73. # should be the name of a menu file 74. 75. if [ ! $# = 1 ] 76. then 77. usage 78. exit 79. fi 80. 81. #--------------------------------------- 82. # TEST THE MENU FILE 83. #--------------------------------------- 84. # Assign the value of the first argument 85. # on the command line, 86. 87. MENU=$1 88. 89. # Test that the file exists and is readable. 90. # Abort if it is not 91. 92. if [ ! -r $MENU ] 93. then 94. echo "Can't locate or read " $MENU 95. echo "Press ENTER to acknowledge." 96. read $answer 97. usage 98. exit 99. fi 100. 101. #--------------------------------------- 102. # MAIN LOGIC 103. #--------------------------------------- 104. # Clear out the error message 105. MSG= 106. 107. #--------------------------------------- 108. # MAIN LOOP 109. #--------------------------------------- 110. # We're here because we have a file 111. # that can be read, so it's OK to 112. # continue with the main loop of the menu. 113. 114. # Repeat the menu over and over 115. # Steps are: 116. # 1. Display the menu 117. # 2. 'read' a line of input from the keyboard 118. # 3. Clear the error message 119. # 4. Check the answer for a or A or b or B etc. and dispatch 120. # to the appropriate program or function or exit 121. # 5. If the entry was invalid call the 122. # badchoice() function 123. # to initialize MSG to an error message 124. # 6. This error message is used when setting 125. # up the menu for a menu pick that is 126. # valid but has no command 127. # associated with it. 128. 129. while true 130. do 131. 132. #--------------------------------------- 133. # READ THE MENU FILE 134. # define the menu by reading in the file 135. # named on the command line 136. #--------------------------------------- 137. . $MENU 138. # <<< mf.mnu begins here >>>> 139. # mf.mnu a simple script menu for shellmenu 140. # This file is read directly into shellmenu 141. # using the dot (.) prefix as in 142. # shellmenu this_file 143. # 144. # causing the contents 145. # of this file to be read as part of the shell script 146. 147. # The logo for this menu will be displayed 148. # at the top of the screen 149. LOGO="More Functions" 150. 151. # Here are the list of menu prompts and the 152. # commands that go with them 153. # In the first list, enter the menu prompt 154. # as it should appear 155. # on the menu for each of the letters A - L 156. # In the second list, replace badchoice 157. # with any commands to run 158. # when that letter is pressed. 159. 160. #--------------------------------------- 161. # MENU PROMPTS 162. #--------------------------------------- 163. amenu="a. Job Scheduling" ; 164. bmenu="b. Set Standard Defaults " ; 165. cmenu="c. Display Directory Listing " ; 166. dmenu="d Other Functions" ; 167. emenu=" " ; 168. fmenu=" " ; 169. gmenu=" " ; 170. hmenu=" " ; 171. imenu=" " ; 172. jmenu=" " ; 173. kmenu=" " ; 174. lmenu=" " ; 175. 176. #--------------------------------------- 177. # MENU ACTIONS AND COMMANDS 178. #--------------------------------------- 179. apick () { shmnu ; } 180. bpick () { defmnt ; } 181. cpick () 182. { 183. ls -l| more ; echo Press Enter ; read DUMMY ; 184. } 185. dpick () {
<font face="Courier">shellmenu</font>
sf.mnu ; } 186. epick () { badchoice ; } 187. fpick () { badchoice ; } 188. gpick () { badchoice ; } 189. hpick () { badchoice ; } 190. ipick () { badchoice ; } 191. jpick () { badchoice ; } 192. kpick () { badchoice ; } 193. lpick () { badchoice ; } 194. 195. # <<< mf.mnu ends here >>>> 196. 197. #--------------------------------------- 198. # DISPLAY THE MENU 199. # and read the user pick 200. #--------------------------------------- 201. displaymenu 202. read answer 203. MSG= 204. # dispatch to the users selection 205. case $answer in 206. a|A) apick;; 207. b|B) bpick;; 208. c|C) cpick;; 209. d|D) dpick;; 210. e|E) epick;; 211. f|F) fpick;; 212. g|G) gpick;; 213. h|H) hpick;; 214. i|I) ipick;; 215. j|J) jpick;; 216. k|K) kpick;; 217. l|L) lpick;; 218. x|X) break;; 219. *) badchoice;; 220. esac 221. done 222. <<
<font face="Courier">End of Listing</font>
>>

The advantage of this second method over the menu version created in last month's issue is that you create only one menu driver program,

<font face="Courier">shellmenu</font>
. The menus themselves can be separated out in individual files.

In listing 4, pick "d" executes the command

<font face="Courier">shellmenu</font>
<font face="Courier">sf.mnu</font>
. The script executes the same
<font face="Courier">shellmenu</font>
program, but this time it is processing a different menu file.

Listing 5 is an example of what

<font face="Courier">sf.mnu</font>
might look like. Listing 5 is stripped of all comments and contains only the menu prompts and commands. The
<font face="Courier">shellmenu</font>
script takes care of the logic of displaying the menu and dispatching to the various menu actions.

Listing 5:

<font face="Courier">sf.mnu</font>
is run by selecting "d" from
<font face="Courier">mf.mnu</font>

LOGO="Some More Functions"
amenu="a.  Edit This Menu"                ;
bmenu="b.  A Directory Listing Wide"      ;
cmenu="c.  Directory Listing Long"        ;
dmenu=" "                                 ;
emenu=" "                                 ;
fmenu=" "                                 ;
gmenu=" "                                 ;
hmenu=" "                                 ;
imenu=" "                                 ;
jmenu=" "                                 ;
kmenu=" "                                 ;
lmenu=" "                                 ;
 apick () { vi sf.mnu ; }
bpick ()
{
ls -C|more ;
echo Press ENTER ;
read DUMMY ;
}
cpick () {
ls -l| more ;
echo Press Enter ;
read DUMMY ;
}
dpick () { badchoice ; }
epick () { badchoice ; }
fpick () { badchoice ; }
gpick () { badchoice ; }
hpick () { badchoice ; }
ipick () { badchoice ; }
jpick () { badchoice ; }
kpick () { badchoice ; }
lpick () { badchoice ; }

<<
<font face="Courier">End of Listing</font>
>>

This should give you some simple examples of menus as well as useful tips on using the shell as a programming language.

Sidebar

 
Listing 1: Sample shell script menu

1.  #!/bin/sh
2.  # sample.mnu
3.  # A simple script menu under Unix
4.  # Main logic starts at MAIN LOGIC
5.  # The logo will be displayed at the top of the screen
6.  LOGO="Sample Menu"
7. 
8.  #------------------------------------------------------
9.  # MENU PROMPTS
10. #------------------------------------------------------
11. # A list of menu prompts to be displayed for the user.
12. # The list can be modified.
13. # In this first list, enter the menu prompt as it should appear
14. # on the screen for each of the letters A - L. In this example
15. # menu pick variables emenu through lmenu are blank as there
16. # are no menu selections for keys E through L.
17. 
18. amenu="a.  Job Scheduling"                ;
19. bmenu="b.  Set Standard Defaults "        ; 
20. cmenu="c.  Display Directory Listing "    ; 
21. dmenu="d   Payroll Menu "                 ;
22. emenu=" "                                 ;
23. fmenu=" "                                 ;
24. gmenu=" "                                 ;
25. hmenu=" "                                 ;
26. imenu=" "                                 ;
27. jmenu=" "                                 ;
28. kmenu=" "                                 ;
29. lmenu=" "                                 ;
30. 
31. #------------------------------------------------------
32. # MENU FUNCTION DEFINITIONS
33. #------------------------------------------------------
34.  
35. # Define a function for invalid menu picks
36. # The function loads an error message into a variable
37. badchoice () { MSG="Invalid Selection ... Please Try Again" ; } 
38.  
39. # For each prompt displayed above, there is a list of 
40. # commands to execute in response to the user picking the
41. # associated letter.
42. # They are defined as functions
43. # apick () through lpick () where
44. # apick () corresponds to the menu
45. # prompt amenu which is selected
46. # selected by pressing a or A.
47. # bpick () corresponds to the menu
48. # prompt bmenu which is selected by
49. # pressing b or B and so on.
50. # Any menu item that is not
51. # assigned a set of commands, is
52. # assigned
53. # the function badchoice () as a default for that pick.
54. # If the user
55. # selects a menu key that is assigned
56. # to badchoice (). This function
57. # causes an error message to be
58. # displayed on the screen.
59. # To add items to this second
60. # list, replace badchoice ()
61. # with the commands to run when
62. # that letter is pressed.
63. # The following steps simply define
64. # the functions, but do not cause
65. # any shell program steps to be executed.
66. 
67. apick () { sched ; }
68. bpick () { defmnt ; }
69. cpick () { ls -l| more ; echo Press Enter ; read DUMMY ; }
70. dpick () { payroll.mnu ; }
71. epick () { badchoice ; }
72. fpick () { badchoice ; }
73. gpick () { badchoice ; }
74. hpick () { badchoice ; }
75. ipick () { badchoice ; }
76. jpick () { badchoice ; }
77. kpick () { badchoice ; }
78. lpick () { badchoice ; }
79. 
80. #------------------------------------------------------
81. # DISPLAY FUNCTION DEFINITION
82. #------------------------------------------------------
83. # This function displays the menu.
84. # The routine clears the screen, echoes
85. # the logo and menu prompts
86. # and some additional messages.
87. # Note that this definition does
88. # not cause the function to
89. # be executed yet, it just defines
90. # it ready to be executed.
91. 
92. themenu () {
93. # clear the screen
94. clear
95. echo `date`
96. echo
97. echo "\t\t\t" $LOGO
98. echo
99. echo "\t\tPlease Select:"
100. echo
101. echo "\t\t\t" $amenu
102. echo "\t\t\t" $bmenu
103. echo "\t\t\t" $cmenu
104. echo "\t\t\t" $dmenu
105. echo "\t\t\t" $emenu
106. echo "\t\t\t" $fmenu
107. echo "\t\t\t" $gmenu
108. echo "\t\t\t" $hmenu
109. echo "\t\t\t" $imenu
110. echo "\t\t\t" $jmenu
111. echo "\t\t\t" $kmenu
112. echo "\t\t\t" $lmenu
113. echo "\t\t\tx. Exit"
114. echo
115. echo $MSG
116. echo
117. echo Select by pressing the letter and then ENTER ;
118. }
119.  
120. #------------------------------------------------------
121. # MAIN LOGIC
122. #------------------------------------------------------
123. # Every thing up to this point has been to define
124. # variables or functions.
125. # The program actually starts running here.
126. 
127. # Clear out the error message variable
128. MSG=
129. 
130. # Repeat the menu over and over
131. # Steps are:
132. # 1. Display the menu
133. # 2. 'read' a line of input from the key board
134. # 3. Clear the error message
135. # 4. Check the answer for a or A or b or B etc. and dispatch
136. #    to the appropriate program or function or exit
137. # 5. If the entry was invalid call the badchoice () function
138. #    to initialize MSG to an error message
139. # 6. This error message is used when setting up the menu
140. #    for a menu pick that is valid but has no command
141. #    associated with it.
142. 
143. while  true
144. do
145. # 1. display the menu
146.   themenu
147. 
148. # 2. read a line of input from the keyboard
149.   read answer
150. 
151. # 3. Clear any error message
152.   MSG=
153. 
154. # 4. Execute one of the defined functions based on the
155. #    letter entered by the user.
156. 
157. # 5. If the choice was E through L, the pre-defined
158. #    function for that pick will execute badchoice ()
159. #    which loads an error message into MSG  
160. 
161.   case $answer in
162.       a|A) apick;;
163.       b|B) bpick;;
164.       c|C) cpick;;
165.       d|D) dpick;;
166.       e|E) epick;;
167.       f|F) fpick;;
168.       g|G) gpick;;
169.       h|H) hpick;;
170.       i|I) ipick;;
171.       j|J) jpick;;
172.       k|K) kpick;;
173.       l|L) lpick;;
174. 
175. #      If the user selects =91x=92 to exit then break out
176. #      of this loop
177.       x|X) break;;
178.  
179. # 6. If the entry was invalid call the badchoice function
180. #    to initialize MSG to an error message
181.         *) badchoice;;
182.  
183.   esac
184. 
185. #     Do it again until the user enters =91x=92.
186. done
187. <<
<font face="Courier"><End of listing></font>
>>
 
Return to article
 

Top 10 Hot Internet of Things Startups
Join the discussion
Be the first to comment on this article. Our Commenting Policies