DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
Automating frequent tasks

How to structure a program

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:


clear
Clear the entire screen.

smso
Put the terminal into reverse video mode.

rmso
Restore the terminal to normal text mode.
You can enter these modes at any time by using the command tput mode, but if you are going to use the command more than once in a shell script it is better to store the control code in a variable and echo it: this saves you from having to run tput every time.

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.


Next topic: Making a command repeat: the for loop
Previous topic: Writing a readability analysis program: an example

© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003