|
|
In general, there are two types of program: batch programs, and interactive programs. The internal structures of batch and interactive programs differ considerably.
A batch program is a typical SCO OpenServer filter. You run it by specifying a target file (and optional flags) at the shell prompt: it runs, possibly prints messages to the standard output, and exits.
An interactive program prints a menu. You select options from the menu: the program then changes its internal state, and prints another menu, until it has assembled all the data it needs to select and execute a routine that carries out some task. It does not exit until you select a quit option from some menu.
Interactive programs are harder to write, so we will start by looking at a short batch program. An explanation of the program follows the code:
1 : #!/bin/ksh 2 : #----------------------------------------------------- 3 : # 4 : # rap -- Readability Analysis Program 5 : # 6 : # Purpose: skeleton for readability analysis of texts. 7 : # 8 : #------------- define program constants here ---------- 9 : # 10 : CLS=`tput clear` 11 : HILITE=`tput smso` 12 : NORMAL=`tput rmso` 13 : # 14 : #---------- initialize some local variables ----------- 15 : # 16 : SCRIPT=$0 17 : help='no'; verbose=' ' ; record=' ' 18 : log=' ' ; next_log_state=' ' ; batch=' ' 19 : file=' '; fname=' ' 20 : # 21 : #----------------- useful subroutines ----------------- 22 : 23 : do_something() 24 : { 25 : # This is a stub function; it does not do anything, yet, 26 : # but shows where a real function should go. 27 : # It contains a dummy routine to get some input and exit. 28 : echo 29 : print "Type something (exit to quit):" 30 : read temp 31 : if [ $temp = "exit" ] 32 : then 33 : exit 0 34 : fi 35 : } 36 : 37 : 38 : _help() 39 : { 40 : echo " 41 : 42 : ${HILITE}Readability Analysis Program${NORMAL} 43 : 44 : A shell/awk demo to determine the readability grade of texts 45 : 46 : Usage: $SCRIPT -hHlb -f <file> 47 : 48 : Either invoke with no options for full menu-driven 49 : activity, or use the following flags: 50 : 51 : -h or -H prints this help 52 : -l log output to file 53 : -f file name of file to check 54 : -b run in batch mode (no menus) 55 : 56 : " 57 : } 58 : # 59 : # 60 : TrapSig() 61 : { 62 : echo "" 63 : echo "Trapped signal $1...`c" 64 : } 65 : # 66 : #========== START OF MAIN BODY OF PROGRAM ============ 67 : # 68 : #------------ define program traps ------------------- 69 : # 70 : for foo in 1 2 3 15 71 : do 72 : trap "TrapSig $foo" $foo 73 : done 74 : # 75 : #---------- parse the command line--------------------- 76 : # 77 : mainline=$* 78 : echo "" 79 : while getopts "hHvlbf:" result 80 : do 81 : case $result in 82 : h|H) help=yes ;; 83 : v) verbose=yes ;; 84 : l) record=yes 85 : next_log_state=off 86 : log=ON ;; 87 : b) batch=yes ;; 88 : f) file=yes 89 : fname=$OPTARG ;; 90 : *) help=yes ;; 91 : esac 92 : done 93 : shift `expr ${OPTIND} - 1` 94 : if [ $help = 'yes' ] 95 : then 96 : _help 97 : exit 1 98 : fi 99 : # 100 : #---------- enter the main program --------------------- 101 : # 102 : while : 103 : do 104 : do_something 105 : done
(Line numbers are provided for reference only, and are not part of the program.)
At first sight this appears to be quite a complicated program, but most of it is used to set up some facilities which will be useful later. The real start of the program is line 10:
09 : #------------- define program constants here ---------- 10 : CLS=`tput clear` 11 : HILITE=`tput smso` 12 : NORMAL=`tput rmso` 13 : # 14 : #---------- initialize some local variables ----------- 15 : # 16 : SCRIPT=$0 17 : help='no'; verbose=' ' ; record=' ' 18 : log=' ' ; next_log_state=' ' ; batch=' ' 19 : file=' '; fname=' ' 20 :
Text following a ``#'' is ignored by the shell. This comes in useful when you want to leave comments in your program for other users.
Lines 10 to 20 set a number of variables. These variables are only used while the program runs: when the script ends, they will not be made available to its parent shell. One set, CLS, HILITE, and NORMAL, are constants; they are not changed during the execution of the program. The second set are variables that the program may use. We initialize them (to a string containing a single <Space> character) in case they have some other meaning within the parent shell from which the script is executed.
It is worth considering lines 10-12 in more detail. Lines of the form variable=`tput mode` use the command tput(C) to obtain the codes necessary to put the terminal into some special mode, for example reverse video mode, or to restore it to normal.
All terminals have the capability to carry out some basic actions when they receive a corresponding control code: for example, positioning the cursor, switching to reverse video, and clearing the screen. Because different terminals use different control codes, the system terminfo database maintains a table of the codes to use for a given capability on any specified terminal. These capabilities are assigned symbolic names, and the terminfo database matches the name to the escape code for each terminal.
tput takes a terminal ``capability'' name and returns the escape sequence to use for the current terminal. In this program, we capture the output from the tput command in a variable for later use. Once you have the control code for a given capability, you can echo the code to your terminal and it will enter whatever mode you specified.
We are using three special terminal-dependent capabilities here:
Lines 23 to 56 define two functions: a stub (which does nothing useful), and a help routine. The stub simply shows where a more complex function will go, when we have written it. (At present, it prompts for an input string; if you type exit the script terminates.) The help routine is similar to the one we looked at in ``More about redirecting input and output''. If it is called later in the script it prints a message and exits, terminating the script. Note the use of the variable $SCRIPT in the help function. SCRIPT is initialized to whatever the name of the function is, when it is executed. (It is used here in case someone renames the script, so that the usage message reflects the current name of the program.)
Note that before you can call a function, it must have been defined
and the shell must have read the definition. Therefore, functions
are defined at the top of a shell script and the actual program
(that calls them) is right at the bottom.