|
|
Quick lessons on shell programmingHow to start writing your own shell scripts |
The various Unix shells can be used for programming as well as simply interpreting commands. This month we get you started with shell programming, showing you first how to define shell functions and then how to tap into their power by integrating them into shell scripts. (2,000 words)
|
Mail this article to a friend |
sh), the Korn Shell (ksh), the C
Shell (csh), the Bourne Again Shell (bash),
is a powerful programming tool.
Although most people are familiar with the ability of the shell to interpret commands as they are typed in at the terminal, many are not familiar with its ability to execute programs or shell scripts. Even more people are not familiar with all of the tools available in a shell script.
The tools that can be used to create a shell script program are all built into the shell -- whichever one you are using -- but they are rarely used in single command lines that are typed in at the terminal.
Functions are a powerful feature of shell programming for the the
Bourne Shell and its derivatives, Korn Shell and bash.
For these exercises type ksh to start the Korn shell
and press Enter. If an error occurs then type sh to
start the Bourne shell and press Enter.
A function is a single command that can be defined to stand in for one or more Unix commands. Using a function involves two steps: defining the function and then invoking or executing the function.
The first safe step to take is to check if the function name that you intend to use is currently in use. In this case you are going to create a function named "greetings." Type greetings and press Enter. You should receive a message that greetings could not be found. If this is not the case, then select another command such as "hi_there" until you find one that is not found:
greetings ksh: greetings: not found
To define a function give the function a standard Unix-type name, in this case greetings, followed by the definition of the function. There are two different versions of the syntax for defining a function. In the example below, either command will define a function named greetings that prints "Hello there" on the screen:
$ function greetings { echo Hello there ; }
$ greetings () { echo Hello there ; }
Type in either command, and you will notice that nothing appears to
happen. All you have done is define the function, but you have not
yet executed it. To execute the function, type its name just as you
would a standard Unix command. The function will execute:
$ greetings
Hello there
$
Expand on this a bit and define the function to include displaying
the environment variable containing the user I.D.:
$ greetings () { echo Hello there $LOGNAME ; }
Now when you type greetings, the message is more personalized.
$ greetings
Hello there mjb
$
A function may be defined to execute multiple commands by separating
the commands with a semi-colon or a newline. The examples below
both define a function named "whatdo" that will list processes
started by the current user. The ps -ef command is
piped in grep to search for lines containing the user
id ($LOGNAME) and the result is piped through more. At
the end of the display "Press Enter" is displayed and a dummy
variable is read from the keyboard until the user presses Enter.
These examples use the two different syntaxes for defining a
function. Note that in the second version, a newline is used to
replace each semi-colon, and after each new line the continuation
prompt (>) is displayed:
$ whatdo () { ps -ef|grep $LOGNAME|more ; echo Press Enter ; read x ; }
or
$ function whatdo {
> ps -ef|grep $LOGNAME|more
> echo Press Enter
> read x
> }
$
Now type whatdo, and you will see a display of your
activities:
$ whatdo
mjb 260 1 7 Jul 31 01 0:04 -ksh
mjb 261 1 0 Jul 31 02 0:01 -ksh
mjb 2293 1 0 10:31:37 03 0:01 -ksh
mjb 2313 260 7 10:45:06 01 0:00 ps -ef
mjb 2314 260 7 10:45:06 01 0:00 grep mjb
mjb 2315 260 7 10:45:06 01 0:00 more
Press Enter
$
Advertisements
Integrating functions into shell scripts
While functions are fine on the command line, their true power comes
about in shell scripts.
First some rules about shell scripts. Ensure that any shell
script you create will run using /bin/sh or
/bin/ksh by
starting the shell script in one of two ways:
- Always start with a blank line.
- Always start with the line
#! /bin/sh or #!
/bin/ksh
The first method will work on older versions of Unix. The second
method has been supported on many versions of Unix for several years
now.
In the following examples, I will use the second version.
In the examples I have shown you so far, functions are used to
create a sort of alias for one or more other commands. Within shell
scripts, functions are used to tidy up the script so that it is more
readable and to avoid having to repeat the same logic over and over.
It frequently makes the logic of a long shell script easier to
follow.
In Listing 1 I have added line numbers to simplify the explanation.
You can type this in as simpmenu using vi or some other
editor. Then change the execution status with chmod a+x
simpmenu.
At lines 4 through 20 a long function named amenu() is
defined. This function clears the screen and displays a set of
prompts in a menu format. Lines 24 through 27 define a
PressEnter() function that asks the user to press ENTER
and then waits for a key press.
Lines 29 through 44 define functions that are to be used or called
in response to each menu pick. Note that each of these three
functions uses a call to PressEnter within the body of
the function. This ability to use a function inside another function
makes programming much easier. Without this ability, the logic of
the PressEnter function would have to be fully typed in
each time within the body of the three main functions that are
executed by the menu.
Up until line 63, no actual program has been run. If the shell
script stopped at this point, nothing would have happened. At line
63 the program begins with a permanent loop (while true) that runs
to line 85. The menu is displayed by calling the function
amenu at line 66. The read command is used to read the
variable answer at line 69. At line 74, a case statement tests the
value in $answer and executes one of the three defined
functions based on the user's choice or issues a break command that
breaks out of the permanent loop.
Listing 1: A simple demonstration of functions
1. #! /bin/ksh
2. # simpmenu, A very simple menu
3.
4. # amenu() defines a function to display a simple menu
5. amenu () {
6. # clear the screen
7. clear
8. echo `date`
9. echo
10. echo "\t\t\tMy Personal Menu"
11. echo
12. echo "\t\tPlease Select:"
13. echo
14. echo "\t\t\t 1. Directory display"
15. echo "\t\t\t 2. Current Activity"
16. echo "\t\t\t 3. Who is logged on"
17. echo "\t\t\t"
18. echo "\t\t\t 0. Exit"
19. echo Select by pressing a number and then ENTER ;
20. }
21.
22. # A function that asks the user to press enter
23. # and waits for the ENTER Key
24. PressEnter () {
25. echo Press Enter
26. read x
27. }
28.
29. # A function for each of the menu picks
30. DirectoryDisplay () {
31. ls -l|more
32. PressEnter
33. }
34.
35. CurrentActivity ()
36. {
37. ps -ef|more
38. PressEnter
39. }
40.
41. WhoIsLoggedOn () {
42. who|more
43. PressEnter
44. }
45.
46. # The main logic for the program displays the menu
47. # gets the users entry and initiates the activity
48. #------------------------------------------------------
49. # MAIN LOGIC
50. #------------------------------------------------------
51. # Every thing up to this point has
52. # just defined functions
53. # The program actually starts running here.
54.
55. # Repeat the menu over and over
56. # Steps are:
57. # 1. Display the menu
58. # 2. 'read' a line of input from the key board
59. # 3. Check the answer for 1, 2, 3 or 0 and dispatch
60. # to the appropriate function or exit
61. # 4 Repeat until 0 is entered
62.
63. while true
64. do
65. # 1. display the menu
66. amenu
67.
68. # 2. read a line of input from the keyboard
69. read answer
70.
71. # 3. Execute one of the defined functions based on the
72. # number entered by the user.
73.
74. case $answer in
75. 1) DirectoryDisplay ;;
76. 2) CurrentActivity ;;
77. 3) WhoIsLoggedOn ;;
78.
79. # If the user selects 0 to exit then break out
80. # of this loop
81. 0) break ;;
82. esac
83.
84. # Do it again until the user enters 0.
85. done
86.
87. # Clear the screen on the way out
88. clear
Listing 2 is the same activity but without functions. It is much
harder to read and contains a lot of duplicate code.
Listing 2: The non function version of listing 1
1. #! /bin/ksh
2. # simpmenu, A very simple menu
3.
4.
5. # The main logic for the program displays the menu
6. # gets the users entry and initiates the activity
7. #------------------------------------------------------
8. # MAIN LOGIC
9. #------------------------------------------------------
10.
11. # Repeat the menu over and over
12. # Steps are:
13. # 1. Display the menu
14. # 2. 'read' a line of input from the key board
15. # 3. Check the answer for 1, 2, 3 or 0 and dispatch
16. # to the appropriate function or exit
17. # 4 Repeat until 0 is entered
18.
19. while true
20. do
21. # 1. display the menu
22. # clear the screen
23. clear
24. echo `date`
25. echo
26. echo "\t\t\tMy personal menu"
27. echo
28. echo "\t\tPlease Select:"
29. echo
30. echo "\t\t\t 1. Directory display"
31. echo "\t\t\t 2. Current Activity"
32. echo "\t\t\t 3. Who is logged on"
33. echo "\t\t\t"
34. echo "\t\t\t 0. Exit"
35. echo Select by pressing a number and then ENTER
36.
37. # 2. read a line of input from the keyboard
38. read answer
39.
40. # 3. Execute commands based on the
41. # number entered by the user.
42.
43. case $answer in
44. 1)
45. ls -l|more
46. echo Press Enter
47. read x ;;
48. 2)
49. ps -ef|more
50. echo Press Enter
51. read x ;;
52. 3)
53. who|more
54. echo Press Enter
55. read x ;;
56.
57. # If the user selects 0 to exit then break out
58. # of this loop
59. 0) break ;;
60. esac
61.
62. # Do it again until the user enters 0.
63. done
64.
65. # Clear the screen on the way out
66. clear
67.
Use functions to tidy up long shell scripts and you will be taking
advantage of one of the powerful features of the shell programming
language.
|
|
Resources
About the author
Mo Budlong is president of King Computer Services, Inc. and has been
involved in Unix development on Sun and other platforms for over 15
years. King Computer Services, Inc. specializes in Unix and Client/Server
consulting and training and currently publishes the COBOL Just In Time Course,
a crash COBOL course to train staff for the Year 2000 problem.
Reach Mo at mo.budlong@sunworld.com.
If you have technical problems with this magazine, contact webmaster@sunworld.com
URL: http://www.sunworld.com/swol-09-1997/swol-09-unix101.html
Last modified: