Sams Teach Yourself Shell Programming in 24 Hours
(Publisher: Macmillan Computer Publishing)
Author(s): Sriranga Veeraraghavan
ISBN: 0672314819
Publication Date: 01/01/99

Previous Table of Contents Next


Hour 21
Problem Solving with Functions

In previous chapters you looked at writing short shell scripts that perform a specific task. In each shell script, you needed to perform a set of common tasks. Some examples of the required tasks are

  Displaying , ERROR, WARNING, and USAGE messages
  Prompting the user for input

In some cases you needed to repeat these tasks, so you used shell functions. You were able to tailor the output of these functions to suit your needs by using arguments. Many of your scripts reused functions developed for other shell scripts.

In this chapter, I will present a library of shell functions that you can use in your shell scripts to perform some common UNIX task. By using and improving on these implementations, you can avoid having to reinvent the wheel when faced with a particular problem.

Creating a Library of Functions

In previous chapters, when you wrote shell scripts that required the use of a function, you added that function to the shell scripts file. In that model, whenever you wanted to use a function in a script, you had to copy it from a different file.

When you have two or three scripts, this is fine, but as the number of scripts you write increases, so do the number of copies of the functions. Say you locate a bug in one of your functions. Imagine how hard it would be to fix every copy of that function if the function is used in ten or more shell scripts.


To reduce the complexity involved in maintaining shell functions, it would be ideal to create a central repository of functions that you could access from your shell script. In other programming languages, a central repository of functions is called a library.

Creating the Library

Creating a library of shell functions is exactly like creating a shell script. The main difference between the two is that a library contains only functions, whereas a script contains both functions and main code.


Main code consists of all the commands in a shell script that are not contained within a function. In the following shell script, lines 1, 2, and 4 are considered main code:
     1  #!/bin/sh
     2  MSG="hello"
     3  echo_error() { echo "ERROR:" $@ >&2 ; }
     4  echo_error $MSG

Line 3, which contains a function definition, is not considered main code.

In comparison, a library of shell functions does not contain any main code. It contains only functions. For example, the following would be considered a library:

#!/bin/sh
echo_error() { echo "ERROR:" $@ >&2 ; }
echo_warning() { echo "WARNING:" $@ >&2 ; }

Notice that this file contains only function definitions.

Strictly speaking, nothing is preventing a library from containing main code. The distinction between a script and a library is purely a conceptual one. To make it simpler for maintenance purposes, you should avoid having anything other than function definitions in a library script.

Including Functions from a Library

To use a set of functions defined in a library, you need to be able to include or require these functions in shell scripts. You can do this by using the . command. Its syntax is as follows:

. file

Here file is the name of a file that contains shell commands. If the shell functions given in the previous example were stored in a file called messages.sh, the command

. messages.sh

can be used to include the functions echo_error and echo_warning into a shell script. As an example, you can rewrite the script

     1  #!/bin/sh
     2  MSG="hello"
     3  echo_error() { echo "ERROR:" $@ >&2 ; }
     4  echo_error $MSG

to use messages.sh as follows:

     1  #!/bin/sh
     2 . $HOME/lib/sh/messages.sh
     3  MSG="hello"
     4  echo_error $MSG

Here you are assuming that the file messages.sh is stored in the directory $HOME/lib/sh. If this directory did not contain messages.sh, an error message similar to the following would be displayed:

sh: /home/ranga/lib/sh/messages.sh: No such file or directory

In most versions of the shell, the shell script exits at this point without executing any other commands. For this reason, most shell scripts include all their function libraries before executing any commands.

Naming Conventions

Unlike other languages, there are no widespread naming conventions for shell libraries or shell functions. Many programmers feel that descriptive names are best for both functions and libraries, whereas others feel that some structure such as that found in the C programming language should be used. In reality, both are good ideas.

Library Naming

For the purposes of this chapter, I assume that the shell functions that are covered are stored in the file

$HOME/lib/sh/libTYSP.sh

This naming scheme provides double redundancy and can be explained as follows:

  The lib in libTYSP.sh indicates that this file is a library. This is similar to the convention used in the C language.
  The .sh in libTYSP.sh indicates that this file contains Bourne shell code.
  The directory $HOME/lib indicates that this file is a library because it resides in the lib (lib as in library) directory.
  The directory $HOME/lib/sh indicates that this file is a Bourne Shell library because it resides in the sh directory under the lib directory.

To use this library in your scripts, you need to include it as follows:

. $HOME/lib/sh/libTYSP.sh

If you put the library in a different directory, say /usr/local/lib/sh/libTYSP.sh, your scripts need to access it as follows:

. /usr/local/lib/sh/libTYSP.sh

Function Naming

For functions, use the following naming scheme:

  printString for functions that display a message. Here String describes the type of message that is displayed.
  promptString for functions that prompt the user for input. Here String is the name of a variable set by the function after reading input from the user.
  getString for functions that retrieve some type of data. Here String describes the information that is retrieved.


Previous Table of Contents Next