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


Usage Statements


Another common use for $0 is in the usage statement for a script, which is a short message informing the user how to invoke the script properly. All scripts used by more than one user should include such a message.

In general, the usage statement is something like the following:

echo "Usage: $0 [options][files]"
Simplifying Script Maintenance

Using $0 as I’ve illustrated is encountered in the install and the uninstall scripts of some software packages.

Because these scripts share many of the same routines and global variables, it is desirable, for ease of maintenance, to merge them into a single script having different behavior depending on the name with which it is invoked.

If you are writing scripts that need to share main routines, consider using such a scheme to simplify maintenance.

If you consider the mytar script given previously, a usage statement would be a helpful addition, in case the script was called with some name other than the two names it knows about. To implement this, change the case statement as follows:

case $0 in
    *listtar) TARGS="–tvf $1" ;;
    *maketar) TARGS="–cvf $1.tar $1" ;;
    *) echo "Usage: $0 [file|directory]"
       exit 0
       ;;
esac

Thus, if the script is invoked as just mytar, you see following message:

Usage: mytar [file|directory]

Although this message describes the usage of the script correctly, it does not inform us that the script’s name was given incorrectly. There are two possible methods for rectifying this:

  Hard coding the valid names in the “usage statement”
  Changing the script to use its arguments to decide in which mode it should run

To demonstrate the use of options, the next section uses the latter method.

Options and Arguments

Options are given on the command line to change the behavior of a script or program. For example, the –a option of the ls command changes the behavior of the ls command from listing all visible files to listing all files. This section shows you how to use options to change the behavior of scripts.


Often you will see or hear options called arguments. The difference between the two is subtle. A command’s arguments are all of the separate strings or words that appear on the command line after the command name, whereas options are only those arguments that change the behavior of the command.

For example, in the following

$ ls –aF fruit

the command is ls, and its arguments are –aF and fruit. The options to the ls command are –aF.

Dealing with Arguments, an Example

To illustrate the use of options, change the mytar script to use its first argument, $1, as the mode argument and $2 as the tar file to read or create.

To implement this, change the case statement as follows:

USAGE="Usage: $0 [-c|-t] [file|directory]"
case "$1" in
    -t) TARGS=""-tvf $2" ;;
    -c) TARGS="-cvf $2.tar $2" ;;
    *) echo "$USAGE"
       exit 0
       ;;
esac

The three major changes are

  All references to $1 have been changed to $2 because the second argument is now the filename.
  listtar has been replaced by –t.
  maketar has been replaced by –c.

Now running mytar produces the correct output:

Usage: ./mytar [-c|-t] [file|directory]

To create a tar file of the directory fruits with this version, use the command

$ ./mytar –c fruits

To list the contents of the resulting tar file, fruits.tar, use the command

$ ./mytar –t fruits

Using basename

Currently, the message displays the entire path with which the shell script was invoked, but what is really required is the name of the shell script. You can correct this by using the basename command.

The basename command takes an absolute or relative path and returns the file or directory name. Its basic syntax is

basename file

For example,

$ basename /usr/bin/sh

prints the following:

sh

Using basename, you can change the variable $USAGE in the mytar script as follows:

USAGE="Usage: 'basename $0' [-c|-t] [file|directory]"

This produces the following output:

Usage: mytar [-c|-t] [file|directory]

You could also have used the basename command in the first version of the mytar script to avoid using the * wildcard character in the case statement as follows:

#!/bin/sh
case 'basename $0' in
    listtar) TARGS="-tvf $1" ;;
    maketar) TARGS="-cvf $1.tar $1" ;;
esac
tar $TARGS

In this version, the basename command allows us to match the exact names with which scripts can be called. This simplifies the possible user interactions and is preferred for that reason.

As an illustration of a potential problem with the original version, you can see that if the script is called

$ ./makelisttar

the original version would use the first case statement, even though it was incorrect, but the new version would fall through and report an error.


Previous Table of Contents Next