Cover V03, I05
Article
Listing 1
Sidebar 1

sep94.tar


Copying and Moving Directories

Ed Schaefer

Perhaps the most basic of all system administration tasks consists of copying and moving files and directories. This article presents three ways of copying/moving directories. The first two are basic "one-liners" using tar and cpio; the third is a move directory shell script, mvdir, that uses the UNIX move command, mv.

Using tar

The tape archive command, tar, can be used to copy all files and directories from one location to another. To copy all files and directories from under /usr/ed to /usr/fred, type:

cd /usr/ed; tar cf - .|(cd /usr/fred; tar xf - )

This command changes to the source directory and creates a tar archive. The "f" option with a dash means use standard output and the period includes the current directory in the archive. Since this command is piped, the standard output of the archive becomes the standard input of the tar extraction creating the required copy. The parenthesis groups commands before the tar extraction takes place.

Using cpio

The copy input-output command, cpio, can also be used to copy directories:

cd /usr/ed; find . -depth -print|cpio -pd /usr/fred

The pass mode, "-p," of cpio allows a list of files piped from the standard input to be copied to the target directory, /usr/fred. Be sure to change to the source directory and then do a find. A find from root such as

find /usr/ed -depth -print...

will create a directory structure under /usr/fred with the full path of the source directory. For example, a file /usr/ed/sample would be moved as /usr/fred/usr/ed/sample.

The mvdir Script

As useful as these one-liners are, they are strictly a copy and not a true move. With the advent of SVID release 2, the UNIX move command, mv, supports moving directories:

mv srcdirectory destdirectory

where each argument is a directory and "destdirectory" does not exist. The mvdir script takes advantage of mv. The pseudo-code for mvdir is as follows:

1. If the destination directory exists, assume the source directory basename moves to the destination directory, keeping the same name.

2. If the destination directory does not exist, assume the source directory basename moves to the the basename of the destination.

3. If the source and destination directories do not exist on the same file system, perform a copy. If the source and destination directories do not exist on the same file system, inodes cannot be moved across file systems.

Source Code Explanation

Lines 19 through 23 check if the source directory is being moved to itself. For example, mv does not allow the following syntax:

mv   .   destdir

If the destination directory exists, the script appends the basename directory to the destination directory (lines 32 through 34).

If the destination directory does not exist, the awk script (lines 36 through 60) returns either

a) the string NO-PATH if no slashes are found, signifying a directory name with no path, or

b) the full path of the directory name minus the basename. For example, if the destination directory were /usr/eds/doc, the string /usr/eds would be returned.

The awk script splits the destination string into an array and rebuilds the directory string up to the last directory name (lines 41 through 55). (Note: awk array usage is non-conventional; see the sidebar "Arrays in awk," for more information.)

If the full path string is neither a directory nor a path (NO-PATH), an error returns (lines 61 through 65).

If the destination directory is a file or a directory, an error returns (lines 68 through 72).

If the source directory shares a common path with the destination directory, an error returns (lines 74 through 79).

If the first character of the source and destination directories is not a slash, the script assumes this is a valid move (lines 81 through 85).

To check for a possible file system move, the code finds the parent file systems of the source and destination directories, if those are not provided (lines 97 through 101).

The awk script (lines 102 through 112) returns a 1 if the directories are on different file systems, else a zero. This section of the code fails if there is a link between the file system and another directory. For example, if /apps is linked to /jet and you attempt to mvdir /usr/eds/doc/some.dir to /apps/some.dir, the awk script cannot determine that /apps and /usr are separate file systems.

If the file systems are different, the script changes to the source directory, makes the destination directory, and then copies the source directory to the destination directory (lines 116 through 124). If the file systems are the same, the script performs a normal move.

Conclusion

Copying files and directories is simplified by using the tar or cpio one-liners. If a copy is not sufficient, use the mvdir shell script.

References

Prata, Stephen, and Donald Martin. UNIX System V Bible: Commands and Utilities. The Waite Group, 1987.

Aho, Alfred, Brian Kernighan, and Peter Weinberger. The Awk Programming Language. Addison-Wesley, 1988.

About the Author

Ed Schaefer is an Informix software developer and UNIX system administrator at jeTECH Data Systems of Moorpark, CA, where he develops Time and Attendance Software. He has been involved with UNIX and Informix since 1987 and was previously head of software development at Marie Callendar Pie Shops of Orange, CA.