5. Directories and Files

Directory Hierarchy and Pathnames

When you log in to UNIX, you are placed in a directory that contains your files. This directory is part of a hierarchy of directories for the entire UNIX system. Your login directory, known as your ``home directory'', is on one path down that hierarchy from the top (the root). Each user's home directory has its own path from the root. You can create subdirectories below your own home directory. And you may need to copy files to or from another user's directory. If so, you must know how to specify pathnames of these directories in order to get to the files in them. (Microcomputer users might compare this UNIX directory structure to a hierarchy of nested folders and files on Macintosh or Windows computers.)

Pathnames can be either ``relative'' or ``absolute''. An absolute pathname begins with a slash (/) and starts at the root. Each successive directory name down the path is also preceded by a slash. When you examined the shell's search path with the echo $PATH command in the previous chapter, you saw some absolute pathnames. The absolute pathname to the home directory for user ``person'' might look like this:

The directory ``person'' contains the names of files in that directory, and it may also identify other directories below it in the hierarchy. ``Person'' is itself under the directory home, That is, the home directory is the ``parent'' of person; subdirectories below person are the ``children'' of person. This hierarchy is (in part):
                  /  |  \
                 /   |   \
                /    |    \
              usr   home  <=== person's parent directory
                   person     <=== person's home directory
                      htdocs    <=== person's subdirectories
                        / \
                       /   \
                      /     \
              index.html   welcome.html

A relative path starts from the directory you are working in and moves downward to a lower directory. Instead of starting with a slash, a relative pathname starts with the name of the first directory below this working directory; each lower directory down the path is prefixed by a slash.

In both absolute and relative pathnames, the rightmost component is either the ultimate directory name, or a file in that directory. For example, suppose ``person'' has two subdirectories: ``htdocs'' and ``stuff'', and ``welcome.html'' is a file in ``htdocs''. If ``person'' is the working directory, then here is a command to display ``welcome.html'':

     cat htdocs/welcome.html 
Another way to display the same file would use an absolute pathname:
     cat /home/person/htdocs/welcome.html 
Remember that the C shell interprets ~person to mean ``the home directory of the user whose login name is person''. Thus, an equivalent command under the C shell would be simply
      cat  ~person/htdocs/welcome.html 

Seeing What is in Your Directory

To see the names of any files or lower-level directories you have in your current working directory, use the ls (list) command. Its simplest form is
which lists the names of any files and directories that do not begin with a period (.). To see ALL the names, use the -a (all) flag:
     ls -a 
Even if you have not yet created any files in your directory, you should see the names ``.login'' and ``.cshrc'' (the C shell's initialization files) and two entries named ``.'' and ``..''. The entry named only ``.'' is the directory you are working in, and ``..'' identifies its parent, even though these directories have full pathnames, too. All directories use ``.'' to refer to their own names and ``..'' to identify their parents.

To see how big your files are, and to see their protection modes, use the -l (long) flag:

     ls -l 
The protection modes determine what actions you and others may perform on the files. What these modes mean and how to change them is described below.

The -F flag is also useful. It marks the names of directories with a trailing slash (/) character and the names of executable files with a trailing asterisk (*). In fact, the command:

     alias ls 'ls -F'
is often included in .login and .cshrc files so that directories and executables are always indicated by the trailing characters.

To see directory information about selected files and lower-level directories, you can use the special characters described in chapter 4. For example, suppose you are ``person'' in the hierarchy shown above, working in your home directory, ~person. If you give the command

     ls h* 
this expands to
     ls htdocs 
and lists the names of files in the subdirectory ``htdocs'' except for files whose names start with a period.

To list the names of all files in the lower directory ``htdocs'', you might use

     ls -a htdocs 
and get something like
     .  ..  welcome.html index.html
Note that this directory, like your home directory, uses . to mean its own name and .. to identify its parent. So to list the names of files in the directory above the current one, you could type
     ls ..  
If you only need to know which files in subdirectory ``htdocs'' have names beginning with ``index'', you could use
     ls htdocs/index* 
     ls htdocs/index[1-9] 
     ls htdocs/index? 
The last two forms would, of course, not list a file named ``index12''.

Note from these examples that the ls command lists files in the working directory only, unless you include the pathname to another directory whose filenames you want to list.

Naming Files and Directories

Whenever you make new directories below your home directory and create files in any of your directories, you must give these directories and files appropriate names. In general, names should include only letters of the alphabet, digits, period (.) and underscore (_). As shown above in the description of the ls command, files whose names begin with period do not show in a directory listing unless you use the -a flag. It is customary for initialization files to begin with a period (like .login or .cshrc). The underscore character is useful for readability in filenames (e.g. test_scores). Most other punctuation characters have special meaning to the shell. Avoid them in filenames or directory names.

A common use of period is to separate a filename into two segments--a base and a suffix. Related files might be those with a common base name and different suffixes, such as

     fortprog.f   fortprog.o
or with different base names and matching suffixes, such as
     prog.c   newsource.c   test.c
Using the period this way, you can select sets of files for particular operations. For example, you could use *.c to select all files whose suffix is ``c''.

Certain programs such as compilers use filename suffixes to determine what action to take when they process files. Examples of this are in chapter 8.

Finally, no file or directory name can exceed 255 characters and no complete pathname can exceed 1024 characters.

Making New Directories and Moving Between Directories

If you have many projects and you want to separate one project's files from another's, you can create a separate subdirectory to contain each file set. Such subdirectories are below your home directory in the hierarchy, and you can make additional subdirectories below these if needed. If you are working in your home directory, you can make a new subdirectory immediately below it by using the mkdir command:
     mkdir name 
where name is the name of your new subdirectory. Suppose you call it ``to_do''. To make another subdirectory, named ``july'', below ``to_do'', you could use
     mkdir to_do/july 
specifying the relative pathname from your home directory to the new subdirectory you are calling ``july''. Or you could move from your home directory to directory to_do first, then make july from there. By moving to subdirectory to_do, you make it your ``working directory''. To move to to_do from your home directory, use the cd (change directory) command:
     cd to_do 
Now you can create the directory july below it by typing just
     mkdir july 
This concept of ``working directory'' is very important. Whatever directory you are currently in is your working directory. Any time you use a filename with no pathname preceding it, that file is assumed to be in your working directory. Thus, if you start from your home directory and type
     cd to_do/july
     cat  project1 
then cat looks for file project1 ONLY in the subdirectory july, the new working directory. It does not look in your home directory or in subdirectory to_do. Likewise, if ``.'' is in the shell's search path, then the shell looks in your working directory for commands it cannot execute directly. This means that where the shell looks depends on where you are when you issue commands.

When you give the cd command with no arguments, it makes your home directory your working directory.

If you use cd very often to change working directories, you may need to be reminded where you are. To display the absolute pathname of your working directory, give the command

which means ``print working directory''.

Moving and Renaming Files and Directories

To move files from one directory to another, use the mv (move) command:
     mv fromname toname
Include the needed path information about the ``from'' or ``to'' directory if it is not your working directory.

For example, suppose you want to move file source.a from your home directory to the next lower directory, Mysources. If Mysources is your working directory, give one of these commands:

     mv ~/source.a source.a 
     mv ../source.a source.a 
If your home directory is the working directory, do it this way:
     mv source.a Mysources/source.a 
The mv command can also be used to rename files and directories. For example,
     mv xyz abc 
simply renames file ``xyz'' to ``abc'' in your working directory, since no directory change is involved. Similarly,
     mv Newstuff Oldstuff
renames the directory ``Newstuff'' to ``Oldstuff'', without affecting the names or contents of the files in ``Newstuff''.

To prevent destroying a file that already exists, include the -i flag. For example, if you type

     mv -i source.a oldsource.a 
and ``oldsource.a'' already exists, mv will ask if you really want to overwrite that old copy with the newer one.

Protecting Files and Directories

Your files and directories are protected from other users' perusal and destruction by protection-mode settings. These settings control who may read, write, and execute your files. To see what the settings are, issue the ls command using the -l (long) flag. To the left of each file or directory name is displayed a sequence of 10 characters, such as
The leftmost character is ``-'' for a filename entry, ``d'' for a directory name entry. The next 9 characters are three triplets of protection settings; the first pertains to you (the owner), the middle triplet pertains to members of your group (if a group has been established), and the rightmost pertains to everyone else.

Thus the first line shown here says the entry is a directory for which you have read (r), write (w), and execute (x) permission and for which everyone else has no privileges at all. The second entry is a file. In this case, you may read and write it, but others can only read it.

To change the protection modes of your files or directories, use the chmod (change mode) command. It has several forms, but the easiest to use is

     chmod [who]oppermission names
where names identifies one or more file or directory names. The whooppermission sequence must be given with no blanks between portions. The who portion can be any combination of
     u  user (owner of the file or directory)
     g  group members
     o  others
     a  all of the above (default if you omit the who argument)
The op is one of
     +  add the designated permission
     -  remove the designated permission
     =  replace all existing permissions for the relevant who with
        the new ones of this chmod command
and permission is any or all of
     r  read:  If chmod is for a file, it allows that file to be
        read, provided the directory containing it has x permission.
        If chmod is for a directory, it allows that directory to be
        listed with filenames only.
     w  write:  If chmod is for a file, it allows that file to be
        written (altered or replaced).  If chmod is for a directory,
        it allows new files to be added to that directory and existing
        files to be removed.

     x  execute:  If chmod is for a file, it makes that file executable
        (see chapter 10).  If chmod is for a directory, it allows a
        detailed listing (if r is also set), and allows files to be read
        or written in that directory according to their individual file
        permission settings.
The usual protection for a directory that you want others to be able to look through is r-x for everybody.


     chmod u=rx *.prog 
permits the owner of all files whose suffix is ``prog'', in the working directory, to read and execute these files. If write privileges had existed for the owner, these privileges are removed. No one other than the owner is affected, and no protection settings of any other files are affected.
     chmod +r abstract
gives everybody permission to read file ``abstract''. No other existing permissions are altered for the file. The directory containing ``abstract'' must have x permission as well, if attempts to read ``abstract'' are to succeed.
     chmod +rx . 
gives everyone permission to read and search the working directory.

Displaying Files in Your Directory

We have already discussed the cat command, which concatenates one or more files to standard output, your terminal. Its format is simply
     cat file1 [file2] ...  
To display files that take up several screens, you may want to use the command
     more file1 [file2] ...  
The more program pauses after each screenful. At the bottom of the screen, it tells you how much of the file has been displayed so far. To see the next screenful, press the space bar. To see just one more line, press Return. For information about other options, type h. To quit without seeing the rest, press q.

If you just want to see the beginning of a file, use the head program:

     head [-n] file 
which displays only the first n lines of the file. The default for n is 10. The tail command shows the last n lines:
     tail [-n] file 

Making Copies of Files

To make a duplicate of a file's contents, use the cp (copy) command:
     cp fromfile tofile 
     cp file directory 
The second form copies a file to a new directory, keeping its original filename. The fromfile and tofile should include appropriate pathnames whenever the files are not in your working directory. Be sure that they are two different files.


     cp myfile Backup/myfile.old 
copies file ``myfile'' to the next lower directory, named ``Backup'', as a file named ``myfile.old''.
     cp ~csaa123/report report
makes a copy of file ``report'' from the home directory of user csaa123 and places it, with the same name, in your working directory. Since you are not changing the file's name, just copying it to the working directory, you could also have typed
     cp ~csaa123/report . 

Removing Files and Directories

To get rid of files you no longer want, use the rm (remove) command:
     rm file1 [file2] ...
If you do not include a pathname, the files are assumed to be in your working directory. If you use any special characters such as * or ? with the rm command, it is a good precaution to add the -i flag, like this:
     rm -i file*
This interactive option displays, one at a time, each candidate for removal. To remove the file, type y (for ``yes'') and press Return. Any other response keeps the file.

Once rm has removed a file, that file cannot be retrieved: there is no ``undelete'' command. So you might want to put this command in your .cshrc file:

     alias rm 'rm -i' 
This will cause rm to always use the -i flag, even if you type rm alone.

If you have a filename that contains one of the shell's special characters, rm might not be able to delete it. (A common case is accidentally creating a filename whose first character is a hyphen.) In this case, use the - flag and put the filename in quotation marks, like this:

     rm - "badname" 
To remove a directory that you no longer need, use rmdir:
     rmdir path
where path is the relative or absolute pathname of the directory. The rmdir command will not delete a directory while it is your working directory, nor will it delete a directory that contains any files (besides . and .. ).

To remove a directory AND any files and subdirectories it contains, as well as files in those subdirectories, use the ``recursive'' switch with the rm command:

     rm -r path
Be Careful--Without also using the -i switch, it's possible to quickly delete entire directory structures. To be safe, use
     rm -ir path

Altering Search Paths

Remember that the shell searches certain directories, in a specific order, to find commands that it cannot execute itself. If you put all of your executable files into a particular directory, you must alter the shell's search path so it will examine this directory. Suppose, for example, that you put all your executable files into the subdirectory ``actions'' just below your home directory. To add this subdirectory to the C shell's search path, give the command:
     setenv PATH ${PATH}:$HOME/actions 
Here ${PATH} means the current value of your search path and $HOME means the name of your home directory. In this case, you have made $HOME/actions the final place the C shell will search. To make the C shell look there first, reverse the positions of $path and $HOME/actions. Put the setenv command in your .cshrc file to make it take effect every time you log in or start a new copy of the C shell.

You may also need to set the PATH variable if you want to use a program outside your own directories and also outside the default search path. For example, a collection of programs to convert graphics files from one format to another is in the directory /usr/local/pbm/bin. To call up any one of these programs without having to give its full pathname, you could add /usr/local/pbm/bin to your search path.

Note: Much of the optional software commonly used on UNIX systems is installed in
     /usr/local/bin      or      /usr/local/gnu/bin

Disk Quotas

You are assigned quotas limiting the amount of disk space you may use. For most accounts, each user is normally assigned a ``soft'' quota of 14000 kilobytes and a ``hard'' quota of 15000 kilobytes. (A kilobyte is actually 1024 bytes, or characters.) If you exceed your ``soft'' quota, you receive a warning message, but you can continue running programs and can log out without losing any files. However, there are two reasons that you should take prompt action to remove unneeded files to get below the soft quota.

The most serious reason is that if you continue using resources, you may reach the ``hard'' quota. If you do, you will not be able to run programs. In fact, a running program will abort if it attempts to use disk space that exceeds the hard quota. Furthermore, when you try to modify existing files, they may get truncated to zero-length files--without warning or notice.

The second reason is that even if you do stay below the hard quota but remain over the soft quota for seven days, you will not be able to alter existing files or create new ones until you get back below the soft quota.

To see how much disk space you are using, give the command

     quota -v 
If you need a higher disk quota than the one originally established, please send email to: support@hardlink.com. There is a charge of 50 cents/meg/month for every meg over 15 megs. Keep in mind that you are charged for the disk space you reserve (i.e., your quota), rather than the disk you actually use; so don't request too much more than you expect to need.

Go to next chapter

Go back to table of contents