| 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 |