Working With Directories
UNIX uses a hierarchical structure for organizing files and directories. This structure is often referred to as a directory tree . The tree has a single root node, the slash character ( /), and all other directories are contained below it.
You can use every directory, including /, to store both files and other directories. Every file is stored in a directory, and every directory except / is stored in another directory.
This is slightly different from the multiroot hierarchical structure used by Windows and Mac OS. In those operating systems, all devices (floppy disk drives, CD-ROMs, hard drives, and so on) are mounted at the highest directory level. The UNIX model is slightly different, but after a short time most users find it extremely convenient.
The Directory Tree
Filenames
Pathnames
To explain the origin and advantages of the directory tree, consider a project that requires organization, such as writing a book.
When you start out, it is easiest to put all the documents related to the book in one location. As you work on the book, you might find it hard to locate the material related to a particular chapter.
If you are writing the book with pen and paper, the easiest solution to this problem is to take all the pages related to the first chapter and put them into a folder labeled "Chapter 1." As you write more chapters, you can put the material related to these chapters into separate folders.
In this method, when you finish the book, you will have many separate folders. You might put all the folders into a box and label that box with the name of the book. (Then you can stack the boxes in your closet.)
By grouping the material for the different chapters into folders and grouping the folders into boxes, the multitude of pages required to write a book becomes organized and easily accessible. When you want to see Chapter 5 from a particular book, you can grab that box from your closet and look only at the folder pertaining to Chapter 5.
You can carry this same method over to a project on your computer. When you start out, all the files for the book might be in your home directory, but as you write more chapters, you can create directories to store the material relating to a particular chapter. Finally, you can group all the directories for the book into a directory named after the book.
As you can probably see, this arrangement creates an upside-down tree with the root at the top and the directories branching off from the root. The files stored in the directories can be though of as leaves.
This brings up the notion of parent directories and child or subdirectories . For example, consider two directories A and B, where directory A contains directory B. In this case, A is called the parent of B, and B is called a child of A.
The depth of the directory tree is limited only by the fact that the absolute path to a file cannot have more than 1,024 characters. I cover absolute paths later in the chapter.
File names
In UNIX, every file and directory has a name associated with it. This name is referred to as the file or directory's filename.
In addition to their filenames, every file and directory is associated with the name of its parent directory. When a filename is combined with the parent directory's name, the result is called a pathname. Two examples of pathnames are
/home/ranga/docs/book/ch5.doc
/usr/local/bin/
As you can see, each of these pathnames consists of several "words" separated by the slash ( /) character. In UNIX, the slash separates directories, whereas the individual words are the names of files or directories. The sum of all the words and the / characters makes up the pathname.
The last set of characters in a pathname is the actual name of the file or directory being referred to: The rest of the characters represent its parent directories. In the first example, the filename is ch5.doc.
The name of a file can be up to 255 characters long and can contain any ASCII character except /. Generally, the characters used in pathnames are the alphanumeric characters ( a to z, A to Z, and 0 to 9) along with periods ( .), hyphens ( -), and underscores ( _).
Other characters, especially the space, are usually avoided because many programs cannot deal with them properly. For example, consider a file with the following name:
A Farewell To Arms
Most programs treat this a four separate files named A, Farewell, To, and Arms, instead of one file.
One thing to keep in mind about filenames is that two files in the same directory cannot have the same name. Thus both of the following filenames
/home/ranga/docs/ch5.doc
/home/ranga/docs/ch5.doc
refer to the same file, but the following filenames
/home/ranga/docs/ch5.doc
/home/ranga/docs/books/ch5.doc
refer to different files because they are located in different directories. In addition, because UNIX is case-sensitive, you can have two files in the same directory whose names differ only by case. UNIX considers the following
/home/ranga/docs/ch5.doc
/home/ranga/docs/CH5.doc
to be different files. This often confuses users coming from the Windows or DOS environments.
Pathnames
In order to access a file or directory, its pathname must be specified. As you have seen, a pathname consists of two parts: the name of the directory and the names of its parents. UNIX offers two ways to specify the names of the parent directory. This leads to two types of pathnames:
- Absolute
- Relative
An Analogy for Pathnames
The following statements illustrate a good analogy for the difference between absolute and relative pathnames:
"I live in San Jose."
"I live in San Jose, California, USA."
The first statement gives only the city in which I live. It does not give any more information, thus the location of my house is relative. It could be located in any state or country containing a city called San Jose. The second statement fully qualifies the location of my house, thus it is an absolute location.
Absolute Pathnames
An absolute pathname represents the location of a file or directory starting from the root directory and listing all the directories between the root and the file or directory of interest.
Because absolute pathnames list the path from the root directory, they always start with the slash ( /) character. Regardless of what the current directory is, an absolute path points to an exact location of a file or directory. The following is an example of an absolute pathname:
/home/ranga/work/bugs.txt
This absolute path tells you that the file bugs.txt is located in the directory work, which is located in the directory ranga, which in turn is located in the directory home. The slash at the beginning of the path tells you that the directory home is located in the root directory.
Relative Pathnames
A relative pathname enables you to access files and directories by specifying a path to that file or directory within your current directory. When your current directory changes, the relative pathname to a file can also change.
To find out what the current directory is, use the pwd (print working directory ) command, which prints the name of the directory in which you are currently located. For example
$ pwd
/home/ranga/pub
tells me that I am located in the directory /home/ranga/pub.
When you're specifying a relative pathname, the slash character is not present at the beginning of the pathname. This indicates that a relative pathname is being used instead of an absolute pathname. The relative pathname is a list of the directories located between your current directory and the file or directory you are representing.
If you are pointing to a directory in your pathname that is below your current one, you can access it by specifying its name. For example, the directory name:
docs/
refers to the directory docs located in the current directory.
In order to access the current directory's parent directory or other directories at a higher level in the tree than the current level, use the special name of two dots ( ..).
The UNIX file system uses two dots ( ..) to represent the directory above you in the tree, and a single dot ( .) to represent your current directory.
Look at an example that illustrates how relative pathnames are used. Assume that the current directory is
/home/ranga/work
Then the relative pathname
represents the file
/home/ranga/docs/ch5.doc
whereas
./docs/ch5.doc
represents the file
/home/ranga/work/docs/ch5.doc
You can also refer to this file using the following relative path:
docs/ch5.doc
As mentioned previously, you do not have to append the ./ to the beginning of pathnames that refer to files or directories located within the current directory or one of its subdirectories.
Switching Directories
Now that you have covered the basics of the directory tree, look at moving around the tree usingthe cd (change directory) command.
Home Directories
First print the working directory:
$ pwd
/home/ranga
This indicates that I am in my home directory. Your home directory is the initial directory where you start when you log in to a UNIX machine. Most systems use either /home or /users as directories under which home directories are stored. On my system I use /home.
The easiest way to determine the location of your home directory is to do the following:
$ cd
$ pwd
/home/ranga
When you issue the cd command without arguments, it changes the current directory to your home directory. Therefore, after the cd command completes, the pwd command prints the working directory that is your home directory.
Changing Directories
You can use the cd command to do more than change to a home directory: You can use it to change to any directory by specifying a valid absolute or relative path. The syntax is as follows:
cd directory
Here, directory is the name of the directory that you want to change to. For example, the command
$ cd /usr/local/bin
Say that the current directory is
$ pwd
/home/ranga
From this directory, you can cd to the directory /usr/local/bin using the following relative path:
$ cd ../../usr/local/bin
Changing the current directory means that all your relative path specifications must be relative to the new directory rather than the previous directory. For example, consider the following sequence of commands:
$ pwd
/home/ranga/docs
$ cat names
ranga
vathsa
amma
$ cd /usr/local
$ cat names
cat: cannot open names
When the first cat command was issued, the working directory was /home/ranga/docs. The file, names, was located in this directory, thus the cat command found it and displayed its contents.
After the cd command, the working directory became /usr/local. Because no file was called names in that directory, cat produces an error message stating that it could not open the file. To access the file names from the new directory, you need to specify either the absolute path to the file or a relative path from the current directory.
Common Errors
The most common errors are
- Specifying more than one argument
- Trying to cd to a file
- Trying to cd to a directory that does not exist
An example of the first case is
$ cd /home /tmp /var
$ pwd
/home
As you can see, cd uses only its first argument. The other arguments are ignored. Sometimes in shell programming, this becomes an issue. When you issue a cd command in a shell script, make sure that you end up in the directory you intended to reach.
$ pwd
/home/ranga
$ cd docs/ch5.doc
cd: docs/ch5.doc: Not a directory
$ pwd
/home/ranga
Here, you tried to change to a location that was not a directory, and cd reported an error. If this error occurs, the working directory does not change. The final pwd command in this example illustrates this.
An example of the third case is
$ pwd
/home/ranga
$ cd final_exam_answers
cd: final_exam_answers: No such file or directory
$ pwd
/home/ranga
Here, I tried to change into the directory final_exam_answers, but because this directory did not exist, cd reported an error. The final pwd command shows that the working directory did not change.
The problem in this last example occurs because none of my professors were kind enough to make a copy of the directory final_exam_answers for me.
Listing Files and Directories
Listing Directories
Listing Files
In "Handling UNIX Files" you looked at using the ls command to list the files in the current
directory. Now look at using the ls command to list the files in any directory.
Listing Directories
To list the files in a directory you can use the following syntax:
ls directory
Here, directory is the absolute or relative pathname of the directory whose contents you want listed.
For example, both of the following commands list the contents of the directory /usr/local (assuming the working directory is /home/ranga):
$ ls /usr/local
$ ls ../../usr/local
On my system the listing looks like
X11 bin gimp jikes sbin
ace doc include lib share
atalk etc info man turboj-1.1.0
The listing on your system might look quite different.
$ ls -aF /usr/local
produces the following output
./ atalk/ gimp/ lib/ turboj-1.1.0/
../ bin/ include/ man/
X11/ doc/ info/ sbin/
ace/ etc/ jikes/ share/
You can specify more than one directory as an argument. For example
$ ls /home /usr/local
produces the following output on my system:
/home:
amma ftp httpd ranga vathsa
/usr/local:
X11 bin gimp jikes sbin
ace doc include lib share
atalk etc info man turboj-1.1.0
A blank line separates the contents of each directory.
Listing Files
If you specify the name of a file instead of a directory, ls lists only that one file. For example
$ ls .profile
.profile
You can intermix files and directories as arguments to ls:
$ ls .profile docs/ /usr/local /bin/sh
This produces a listing of the specified files and the contents of the directories.
If you don't want the contents of the directory listed, specify the -d option to ls. This forces ls to display only the name of the directory, not its contents:
$ ls -d /home/ranga
/home/ranga
You can combine the -d option with any of the other ls options you have covered. An example of this is
$ ls -aFd /usr/local /home/ranga /bin/sh
/bin/sh* /home/ranga/ /usr/local/
Common Errors
If the file or directory you specify does not exist, ls reports an error. For example
$ ls tomorrows_stock_prices.txt
tomorrows_stock_prices.txt: No such file or directory
If you specify several arguments instead of one, ls reports errors only for those files or directories that do not exist. It correctly lists the others. For example
$ ls tomorrows_stock_prices.txt /usr/local .profile
produces an error message
tomorrows_stock_prices.txt: No such file or directory
/usr/local:
X11 bin gimp jikes sbin
ace doc include lib share
atalk etc info man turboj-1.1.0
.profile
Manipulating Directories
Creating Directories Moving Files and Directories
Copying Files and Directories Removing Directories
Now that you have covered using directories, look at manipulating them. The most common manipulations are
- Creating directories
- Copying directories
- Moving directories
- Removing directories
Creating Directories
You can create directories with the mkdir command. Its syntax is
mkdir directory
Here, directory is the absolute or relative pathname of the directory you want to create. For example, the command
$ mkdir hw1
creates the directory hw1 in the current directory. Here is another example:
$ mkdir /tmp/test-dir
This command creates the directory test-dir in the /tmp directory. The mkdir command produces no output if it successfully creates the requested directory.
If you give more than one directory on the command line, mkdir creates each of the directories. For example
$ mkdir docs pub
creates the directories docs and pub under the current directory.
Creating Parent Directories
Sometimes when you want to create a directory, its parent directory or directories might not exist. In this case, mkdir issues an error message. Here is an illustration of this:
$ mkdir /tmp/ch04/test1
mkdir: Failed to make directory "/tmp/ch04/test1"; No such file or directory
In such cases, you can specify the -p (p as in parent) option to the mkdir command. It creates all the necessary directories for you. For example
$ mkdir -p /tmp/ch04/test1
creates all the required parent directories.
The mkdir command uses the following procedure to create the requested directory:
1. The mkdir command checks whether the directory /tmp exists. If it does not exist, it is created.
2. The mkdir command checks whether the directory /tmp/ch04 exists. If it does not exist, it is created.
3. The mkdir command checks whether the directory /tmp/ch04/test1 exists. If it does not, it is created.
Common Errors
The most common error in using mkdir is trying to make a directory that already exists. If the directory /tmp/ch04 already exists, the command
$ mkdir /tmp/ch04
generates an error message similar to the following:
mkdir: cannot make directory '/tmp/ch04': File exists
An error also occurs if you try to create a directory with the same name as a file. For example, the following commands
$ ls -F docs/names.txt
names
$ mkdir docs/names
result in the error message
mkdir: cannot make directory 'docs/names': File exists
If you specify more than one argument to mkdir, it creates as many of these directories as it can. Any directory that could not be created generates an error message.
Copying Files and Directories
Already we looked at using the cp command to copy files. Now look at using it to copy directories.
To copy a directory, you specify the -r option to cp. The syntax is as follows:
cp -r source destination
Here, source is the pathname of the directory you want to copy, and destination is where you want to place the copy. For example
$ cp -r docs/book /mnt/zip
copies the directory book located in the docs directory to the directory /mnt/zip. It creates a new directory called book under /mnt/zip.
Copying Multiple Directories
In the same way that you can copy multiple files with cp, you can also copy multiple directories. If cp encounters more than one source, all the source directories are copied to the destination. The destination is assumed to be the last argument.
For example, the command
$ cp -r docs/book docs/school work/src /mnt/zip
copies the directories school and book, located in the directory docs, to /mnt/zip. It also copies the directory src, located in the directory work, to /mnt/zip. After the copies finish, /mnt/zip looks like the following:
$ ls -aF /mnt/zip
./ ../ book/ school/ src/
You can also mix files and directories in the argument list. For example
$ cp -r .profile docs/book .kshrc doc/names work/src /mnt/jaz
copies all the requested files and directories to the directory /mnt/jaz.
If your argument list consists only of files, the -r option has no effect.
Common Errors
The most common error in copying files and directories is in the requested destination. The most common problems in copying directories involve using a destination that is not a directory.
An example of this is
$ cp -r docs /mnt/zip/backup
cp: cannot create directory '/mnt/zip/backup': File exists
$ ls -F /mnt/zip/backup
/mnt/zip/backup
As you can see, the cp operation fails because a file called /mnt/zip/backup already exists.
Moving Files and Directories
You have looked at the mv command to rename files, but its real purpose is to move files and directories between different locations in the directory tree. The basic syntax is this:
mv source destination
Here source is the name of the file or directory you want to move, and destination is the directory where you want the file or directory to end up. For example
$ mv /home/ranga/names /tmp
moves the file names located in the directory /home/ranga to the directory /tmp.
Moving a directory is exactly the same:
$ mv docs/ work/
moves the directory docs into the directory work. To move the directory docs back to the current directory you can use the command:
$ mv work/docs .
One nice feature of mv is that you can move and rename a file or directory all in one command. For example
$ mv docs/names /tmp/names.txt
moves the file names in the directory docs to the directory /tmp and renames it names.txt.
Moving Multiple Items
As you can with cp, you can specify more than one file or directory as the source. For example
$ mv work/ docs/ .profile pub/
moves the directories work and docs along with the file .profile into the directory pub.
When you are moving multiple items, you cannot rename them. If you want to rename an item and move it, you must use a separate mv command for each item.
Common Errors
You can encounter three common errors with mv:
- Moving multiple files and directories to a directory that does not exist
- Moving files and directories to a file
- Trying to move directories across file systems
The first and second cases produce the same error message, so look at one example that illustrates what happens:
$ mv .profile docs pub /mnt/jaz/backup
mv: when moving multiple files, last argument must be a directory
$ ls -aF /mnt/jaz
./ ../ archive/ lost+found/ old/
As you can see, no directory named backup exists in the /mnt/jaz directory, so mv reports an error. The same error is reported if backup was a file in the /mnt/jaz directory.
The third case occurs when you try to move a directory from one file system to another. For the purposes of this book, you can think of a file system as either a hard drive or a hard drive partition.
Assume that /home and /tmp are on separate partitions. In this case, the command
$ mv /tmp/ch01 /home/ranga/docs
returns error output
mv: cannot move '/tmp/ch01' across filesystems: Not a regular file
The most common workaround to this is to use the cp -r to copy the directory and then remove the original with rm:
$ cp -r /tmp/ch01 /home/ranga
$ rm -r /tmp/ch01
I cover the -r option of rm later in this chapter.
Sometimes, you might use the tar (as in tape archive) command instead of cp:
$ ( cd /tmp ; tar -cvpf - ch01 | ( cd /home/ranga ; tar -xvpf -) )
$ rm -r /tmp/ch01
Removing Directories
You can use two commands to remove directories:
- rmdir
- rm -r
Use the first command to remove empty directories. It is considered "safe" because in the worst case, you can accidentally lose an empty directory, which you can quickly re-create with mkdir.
The second command removes directories along with their contents. It is considered "unsafe" because in the worst case of rm -r, you could lose your entire system.
Caution - When using rm to remove either files or directories, make sure that you remove only those files that you don't want.
There is no way to restore files deleted with rm, so mistakes can be very hard to recover from.
rmdir
To remove an empty directory, you can use the rmdir command. Its syntax is
rmdir directories
Here, directories includes the names of the directories you want removed. For example, the command
$ rmdir ch01 ch02 ch03
removes the directories ch01, ch02, and ch03 if they are empty. The rmdir command produces no output if it is successful.
Common Errors
You might encounter two common error messages from rmdir. These occur when you
- Try to remove a directory that is not empty
- Try to remove files with rmdir
For the first case, you need to know how to determine whether a directory is empty. You can do this by using the -A option of the ls command. An empty directory produces no output. If there is some output, the directory you specified is not empty.
For example, if the directory bar is empty, the following command
$ ls -A bar
Now say that the directory docs is not empty. The following command
$ rmdir docs
produces an error message
rmdir: docs: Directory not empty
To illustrate the second error, assume that names is a file. The following command
$ rmdir names
produces an error message
rmdir: names: Not a directory
rm -r
You can specify the -r option to rm to remove a directory and its contents. The syntax is as follows:
rm -r directories
Here directories includes the names of the directories you want removed.
For example, the command
$ rm -r ch01/
removes the directory ch01 and its contents. This command produces no output.
You can specify a combination of files and directories as follows:
$ rm -r ch01/ test1.txt ch01-old.txt ch02/
In order to make rm safer, you can combine the -r and -i options.
Common Errors
Usually the only error reported by rm is that a requested file or directory cannot be removed. If the file or directory midterm_answers does not exist, rm reports an error:
$ rm -r midterm_answers
rm: midterm_answers: No such file or directory
Summary
In this blog, you have looked at working with directories. Specifically, you covered the following topics:
- Working with filenames and pathnames
- Switching directories
- Listing files and directories
- Creating directories
- Copying and moving directories
- Removing directories
You reviewed each of these topics because it is important to know how to perform these functions when writing shell scripts. As you progress further into this book, you see how common directory manipulations occur in shell scripts.
Questions
1. Which of the following are absolute pathnames? Which are relative?
a. /usr/local/bin
b. ../../home/ranga
c. docs/book/ch01
d. /
2. What is the output of the pwd command after the following sequence of cd commands have been issued?
$ cd /usr/local
$ cd bin
$ cd ../../tmp
$ cd
3. What command should be used to copy the directory /usr/local to /opt/pgms?
4. What command(s) should be used to move the directory /usr/local to /opt/pgms?
5. Given the following listing for the directory backup, can you use the rmdir command to remove this directory? If not, please give a command that can be used.
$ ls -a backup
./ ../ sysbak-980322 sysbak-980112
No comments:
Post a Comment