As a shell programmer becomes more experienced, he will undoubtably want to write increasingly more complex shell scripts to handle more interesting tasks. With more complex tasks come larger more complex programs. As in any computer language, large programs can become cumbersome and difficult to understand. This can be a real problem when attempting to maintain scripts. One way that programmers have managed to keep complicated programs clear and hence easily maintainable is to modularize the programs. This means to write programs in blocks or modules, where each module contains a group of commands specific to a certain subtask of the whole program. An example of this would be a program written in any generic language to calculate the sum of areas of a circle, square, and a triangle. While it would be possible to write the program sequentially, using modules gives the program a certain clarity that can not easily be achieved any other way:
begin areasum circ_area () area = Pi * rad * rad return area squar_area () area = side * side return area tri_area () area = 1/2 base * height return area sum = circ_area + squar_area + tri_area end
These modules are often called subroutines or functions.
The difference between the meanings is language dependent.
In Bourne shell programming, these modules are called functions.
Another reason, even more valuable than maintenance, for using
functions is the ability to repeat a task many times without having to
re-enter the same code whenever it is needed.
A good example of this is a sine function.
A program which tracks a sattelite may have to calculate a sine
function many times.
If the list of commands to calculate the sine function had to be
written in to the program for each time it was to be used, the length
of the program would be ridiculous.
Instead, a function which calculates the sine of a number would be
written once in a function and called when needed.
In shell programming it may become necessary to repeat a task many
times in the context of a larger task.
For example, consider a function which might examine a file and print
out information pertaining to a particular string contained in the
file.
The actual program might examine many directories containing many
different files, but only want to examine a certain type of file for
this string.
The main shell script could then call this function only when it is
needed rather than have it operate on all of the files examined by the
main program.
This could save the user much time and make his entire program more
efficient.
The following example of a function is an enhancement of the long
listing in UNIX (ls -l) in that it displays a title over each
of the columns of information diplayed:
$ list () {
> echo ``Permission Ln Owner Group Size Modified Name''
> echo ``---------- -- ----- ----- ---- -------- ----''
> ls -l $*;
>}
which could be used as follows:
$ list Permission Ln Owner Group Size Modified Name ---------- -- ----- ----- ---- -------- ---- total 86 -rwx-r---- 1 normb users 60041 Dec 15 19:48 Bourne.tex drwx------ 2 normb users 1024 Sep 18 3:13 mail/ drwxr-xr-x 2 normb users 1024 Sep 30 11:01 tmp/ $
Because of the use of the $* variable this long listing
function will also take wildcards (or filename meta-characters).