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 22
Problem Solving with Shell Scripts

In Chapter 21, “Problem Solving with Functions,” I showed you several useful functions that you can use in your shell scripts. In this chapter, I will present two shell scripts that demonstrate how you can use shell scripts to solve everyday problems.

These scripts illustrate using the tools I covered in previous chapters to create new tools that you can reuse. For each script I will first describe the motivations for its development, followed by some design issues. Then I will present the script in full. I will conclude the discussion of scripts by highlighting the script’s flow and error checking.

The two tasks that I will look at are

  Moving directories
  Maintaining an Address Book

Moving Directories


In Chapter 4, “Working with Directories,” I noted that the mv command could not be used to move directories across file systems. A file system can be thought of as a hard drive or hard drive partition.


The mv command works fine when you want to move a directory between different locations on the same file system (hard drive), but it doesn’t work well when you want to move a file across file systems. Depending on your version of mv, an error message could be generated when you try to do this.

For example, consider this directory:

$ ls -F /tmp/ch22
ch22-01.doc ch22.doc@

If you use the mv command to move this directory in the directory /home/ranga on a different file system, an error message similar to the following is generated:

mv: cannot move 'ch22' across filesystems: Not a regular file

Some UNIX versions implement a workaround inside mv that executes the following commands:

$ rm -rf destination
$ cp -r source destination
$ rm -rf source

Here source and destination are directories.

The main problem with this strategy is that links in the source directory are not always copied correctly. Most of the time, the file that the link points to is copied instead of the link itself. In the case of the directory /tmp/ch22, you would end up with two copies of the file ch22-01.doc, which is not desirable.

In addition to this, there are two other minor problems with using cp:

  Some versions of the cp command do not copy a file’s owner and group. With these versions of cp, the copied file has a different owner and group than the original.
  Some versions of cp do not copy a file’s permissions correctly. With such a version of cp, the copied file might have different permissions than the original.

Using tar


The workaround for these problems is to use the tar (tar as in tape archive) command to copy directories. This command creates an archive or tar file that contains files and directories. A tar file is similar to a zip file, except that its contents are not compressed. In addition, a tar file stores the file permission along with group and owner information for the files it contains. Thus by using tar, your copies automatically end up with the correct file attributes.


By using tar you can move directories using the following procedure:

1.  Make a tar file of the source directory.
2.  Change to the destination directory.
3.  Extract the source directory in the destination directory.
4.  Remove the source directory. Notice that your procedure does not include deleting the tar file of the source directory. Normally when you use the tar command, a tar file is created on your hard drive. If you use this behavior in your script, you need to worry about cleaning up the tar file whenever an error occurs. This adds a large amount of complexity to your script. To avoid all that unnecessary complexity, you can use a special feature of the tar command to avoid creating a tar file.

The tar command can create archives and write them to STDOUT instead of a file. It can also read archives from STDIN instead of from a file. By using a pipe character (|), you can connect a tar command that creates a tar file with one that extracts a tar file, thus avoiding the creation of an intermediate tar file.

To create a tar file, use the following command:

tar -cpf - source

Here source is the pathname of a directory. The options specified to tar tell it to create a tar file, whereas the - indicates that the tar file it creates should be written to STDOUT.

To extract a tar file from STDIN, use the command:

tar -xpf -

Here the options specified to tar indicate that it should extract a tar file, whereas the - indicates that the tar file should be read from STDIN.

Because you need to extract the tar file in the correct directory, the final command you use is

tar -cpf - source | ( cd destination ; tar -xpf -)

Here source and destination are directories. This single command takes care of the first three steps involved in moving a directory. The rest of your script performs error checking and ensures that sensible values for source and destination are used.


Previous Table of Contents Next