Tuesday, September 4, 2012

Working With UNIX Directories


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


 ../docs/ch5.doc

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


 changes to the directory /usr/local/bin. Here, you used an absolute path.

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.


 An example of the second case is

$  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


 returns nothing.

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