Previous | Table of Contents | Next |
The script mvdir.sh is given in Listing 22.1 (the line numbers are provided for your reference).
Listing 22.1 Complete Listing of the mvdir.sh Script
1 #!/bin/sh 2 # Name: mvdir 3 # Desc: Move directories across file systems 4 # Args: $1 -> src dir 5 # $2 -> dest dir 6 7 PATH=/bin:/usr/bin ; export PATH 8 9 # function to print errors and exit 10 11 printERROR() { echo "ERROR: $@." >&2 ; exit 1; } 12 13 # function to print usage message and exit 14 15 printUSAGE() { echo "USAGE: '/bin/basename $0' $@." >&2 ; ⇒exit 1; } 16 17 # check whether sufficient args are given 18 19 if [ $# -lt 2 ] ; then printUSAGE "[src] [dest]" ; fi 20 21 # check whether the source directory exists 22 23 if [ ! -d "$1" ] ; then 24 printERROR "The source $1 is not a directory, or does ⇒not exist" 25 fi 26 27 # split up the source dir into its name and its parent's 28 # name for easier processing later on 29 30 SRCDIR_PARENT="'/usr/bin/dirname $1'" 31 SRCDIR_CHILD="'/bin/basename $1'" 32 33 # if dirname returns a relative dir we will be confused 34 # after cd'ing later on. So reset it to the full path. 35 36 SRCDIR_PARENT="'(cd $SRCDIR_PARENT ; pwd ;)'" 37 38 # check whether the destination exits 39 40 if [ -d "$2" ] ; then 41 42 DESTDIR='( cd "$2" ; pwd ;)' 43 44 else 45 46 # if the destination doesn't exist then assume the 47 # destination is the new name for the directory 48 49 DESTDIR="'/usr/bin/dirname $2'" 50 NEWNAME="'/bin/basename $2'" 51 52 # if dirname returns a relative dir we will be confused 53 # after cd'ing later on. So reset it to the full path. 54 55 DESTDIR='(cd $DESTDIR ; pwd ;)' 56 57 # if the parent of the destination doesn't exist, 58 # we're in trouble. Tell the user and exit. 59 60 if [ ! -d "$DESTDIR" ] ; then 61 printERROR "A parent of the destination directory ⇒$2 does not exist" 62 fi 63 64 fi 65 66 # try and cd to the parent src directory 67 68 cd "$SRCDIR_PARENT" > /dev/null 2>&1 69 if [ $? -ne 0 ] ; then 70 printERROR "Could not cd to $SRCDIR_PARENT" 71 fi 72 73 # use tar to copy the source dir to the destination 74 75 /bin/tar -cpf - "$SRCDIR_CHILD" | ( cd "$DESTDIR" ; ⇒/bin/tar -xpf -) 76 77 if [ $? -ne 0 ] ; then 78 printERROR "Unable to successfully move $1 to $2" 79 fi 80 81 # if a rename of the copy is requested 82 83 if [ -n "$NEWNAME" ] ; then 84 85 # try and change to the destination directory 86 87 cd "$DESTDIR" > /dev/null 2>&1 88 if [ $? -ne 0 ] ; then 89 printERROR "Could not cd to $DESTDIR" 90 fi 91 92 # try and rename the copy 93 94 /bin/mv "$SRCDIR_CHILD" "$NEWNAME" > /dev/null 2>&1 95 if [ $? -ne 0 ] ; then 96 printERROR "Could not rename $1 to $2" 97 fi 98 99 # return to the original directory 100 101 cd "$SRCDIR_PARENT" > /dev/null 2>&1 102 if [ $? -ne 0 ] ; then 103 printERROR "Could not cd to $SRCDIR_PARENT" 104 fi 105 fi 106 107 # try and remove the original 108 109 if [ -d "$SRCDIR_CHILD" ] ; then 110 /bin/rm -r "$SRCDIR_CHILD" > /dev/null 2>&1 111 if [ $? -ne 0 ] ; then 112 printERROR "Could not remove $1" 113 fi 114 fi 115 116 exit 0
Ill walk through the script and highlight some of the important points.
The first thing this script does is set the PATH variable (line 7). You do this to ensure that all the commands you use come from one of the two directories that you specified. When you write a script that can be run by many users, you have to take into account that some users might have modified their PATH such that the commands you are using are inaccessible or replaced by other versions. By setting the PATH variable explicitly, you avoid this problem.
Next the script defines a few utility functions (lines 11 and 15) used to print error usage messages. You can easily modify the script to replace these functions with the versions I gave you in Chapter 21.
After this the script validates its arguments as follows:
If at least two arguments are not given, you cannot be sure what the user wanted to move. Thus a usage message is printed and the script exits. If the source is not a directory or doesnt exist, there is nothing to move, thus the script prints an error message and exits.
The next two lines (lines 30 and 31) are used to access the different parts of the pathname for the source. If the user specifies a directory as follows
$ mvdir.sh /tmp/mydir /home/ranga
there are two pieces of information you need:
When you issue the mv or cp command, each performs this separation internally. Because this is a shell script, you have to do it explicitly using the dirname and basename commands.
One problem you run into is when the user specifies a relative path. When a cd command is used, the relative path required to access the source and destination directories changes; thus you need to determine the absolute path to the SRCDIR_PARENT. By using a subshell, you can make this determination in one line (line 36).
Previous | Table of Contents | Next |