CONTENTS

Chapter 7. Directory Organization

7.1 What? Me, Organized?

Computers and offices have one thing in common: you lose things in them. If you walk into my office, you'll see stacks of paper on top of other stacks of paper, with a few magazines and business cards in the mix. I can often find things, but I'd be lying if I said that I could always find that article I was reading the other day!

When you look at a new computer user's home directory (Section 31.11) , you often see something similar to my office. You see a huge number of unrelated files with obscure names. He hasn't created any subdirectories, aside from those the system administrator told him they needed; and those probably aren't even being used. His home directory probably contains programs for several different projects, personal mail, notes from meetings, a few data files, some half-finished documentation, a spreadsheet for something he started last month but has now forgotten, and so on.

Remember that a computer's filesystem isn't that much different from any other filing system. If you threw all of your papers into one giant filing cabinet without sorting them into different topics and subtopics, the filing cabinet wouldn't do you much good at all: it would just be a mess. On a computer, the solution to this problem is to sort your files into directories, which are analogous to the filing cabinets and drawers.

The Unix filesystem can help you keep all of your material neatly sorted. Your directories are like filing cabinets, with dividers and folders inside them. In this chapter, we'll give some hints for organizing your computer "office." Of course, things occasionally get misplaced even in the most efficient offices. Later we'll show some scripts that use the find (Section 8.3) and grep (Section 9.21) commands to help you find files that are misplaced.

— ML

7.2 Many Homes

Various operating systems store users' home directories in many places, and you've probably already noticed evidence of this throughout this book. Home directories may be in /home/username, /u/username, /Users/username, or some other, more esoteric location.

The simplest way to find out where your system believes your home directory to be is to take advantage of the fact that cd with no arguments changes to your home directory:

% cd
% pwd
/home/users/deb

Generally, the $HOME environment variable will point to your home directory:

% echo $HOME
/home/users/deb

Most shells also expand tilde (~) to a user's home directory as well, so ~/archive on my machine becomes /home/users/deb/archive and ~joel/tmp expands to /home/users/joel/tmp.

Your home directory is set in your /etc/passwd entry (or equivalent — Netinfo on Darwin and NIS on Solaris store the same information, for example). There is no actual requirement that all users' home directories be in the same directory. In fact, I've seen systems that have lots of users organize home directories by the first few letters of the username (so my home directory there was /home/d/de/deb).

If you add user accounts using a tool rather than by using vipw and adding them by hand, take a peek at the documentation for your tool. It should tell you both where it wants to put home directories by default and how to change that default should you want to.

— DJPH

7.3 Access to Directories

Unix uses the same mode bits (Section 50.2) for directories as for files, but they are interpreted differently. This interpretation will make sense if you remember that a directory is nothing more than a list of files. Creating a file, renaming a file, or deleting a file from a directory requires changing this list: therefore, you need write access to the directory to create or delete a file. Modifying a file's contents does not require you to change the directory; therefore, you can modify files even if you don't have write access to the directory (provided that you have write access to the file).

Reading a directory is relatively straightforward: you need read access to list the contents of a directory (find out what files it contains, etc.). If you don't have read access, you can't list the contents of the directory. However (surprise!), you may still be able to access files in the directory, provided that you already know their names.

Execute access for a directory has no meaning per se, so the designers of Unix have reassigned this. It is called the search bit. Search access is needed to perform any operation within a directory and its subdirectories. In other words, if you deny execute access to a directory, you are effectively denying access to the directory and everything beneath it in the directory tree. Note that providing search access to a directory without read access prevents people from listing the directory, but allows them to access files if they know their names. This is particularly useful in situations where you want to allow public access to areas, but only to people who know exactly what files to access; files available via a web server are a good example.

The SUID bit (Section 50.4) is meaningless for directories, but the SGID bit set on a directory affects group ownership of files created in that directory, and the sticky bit prohibits users with write access to the directory from deleting or renaming files that they don't own.

The exception is, of course, that the superuser can do absolutely anything at any time.

— ML

7.4 A bin Directory for Your Programs and Scripts

If you compile programs or write shell scripts, it's good to put them in one directory. This can be a subdirectory of your home directory. Or, if several people want to use these programs, you could pick any other directory — as long as you have write access to it. Usually, the directory's name is something like bin — though I name mine .bin (with a leading dot) to keep it from cluttering my ls listings.

For instance, to make a bin under your home directory, type:

% cd
% mkdir bin

Once you have a directory for storing programs, be sure that the shell can find the programs in it. Type the command echo $PATH and look for the directory's pathname. For instance, if your directory is called /u/walt/bin, you should see:

% echo $PATH
...:/u/walt/bin:...

If the directory isn't in your PATH, add it in your .profile or .cshrc.

If other people are using your bin directory, use a command like chmod go+rx bin to give them access. If you're concerned about security, prevent unauthorized users from adding, removing, or renaming files in your directory by making sure that only you have write access; you can do this with a command like chmod go-w bin. Also be sure that individual files can't be edited by people who shouldn't have access to the files.

When you add a new program to your bin directory, if you use the C shell or a C-shell derivative, you need to use the shell's rehash command to update its command search path.

— JP

7.5 Private (Personal) Directories

You might want to create a private directory for your personal files: love letters, financial data, complaints about your boss, off-color jokes, or whatever you want to keep there. While you can set any directory you own to be private, having one in your home directory is convenient to organize all of your private directories together. For simplicity, you can just name it private; giving it a less obvious name, however, can make it more difficult for prying eyes to discover.

Once you've created a private directory, you should set its file access mode ( Section 50.2) to 700; this means that you're the only person allowed to read, write, or even list the files that are in the directory. Here's how:

% mkdir private
% chmod 700 private

On any Unix system, anyone who knows the root password can become superuser (Section 49.9) and read any files he wants. So a private personal directory doesn't give you complete protection by any means — especially on systems where most users know the root password. If you really need security, you can always encrypt your files.

—ML and DJPH

7.6 Naming Files

Let's think about a filing cabinet again. If the files in your filing cabinet were called letter1, letter2, letter3, and so on, you'd never be able to find anything — the names aren't descriptive enough. The same is true on your computer — you should come up with a descriptive name for each file that you create. Unix systems let you have very long filenames. A few older systems have a 14-character limit, but most allow names that are 256 characters long — hopefully, longer than you will ever need.

Generally, a descriptive filename summarizes the contents with a few useful words. letter is not a terribly useful summary, unless perhaps you've only ever written one letter and don't expect to write another. The recipient's name (JohnShmoe, for example) would only be a useful summary if you expect to send only one letter to that person. Even if you only plan to send one letter, the name doesn't tell you anything about what you sent Mr. Shmoe.

OctoberGoldPriceTrends is a pretty good summary; it's obvious what the contents of that file are, though you might want to know to which year it referred, looking back two years from now. I often start time-specific files with the date, so that ls sorts the files in date order. If you do this, I recommend a YYYYMMDD format to get proper sorting, so files look like 20021004-GoldPrices. If you're going to have regular updates to something, you might want to make a directory to hold those things (e.g., GoldPrices/20021004, GoldPrices/20021108, GoldPrices/20021206, and so forth). Note that in this specific example, a filename of nothing but a date makes sense, because you don't have anything else in that directory but information on gold prices.

Bruce Barnett has suggested that, by using long filenames, you can create a simple "relational database." For example, you could find out everything you've recorded about the price of gold with a command like more *Gold*Price*. Of course, if this starts to get very complex, using an actual database is much simpler.

Similarly, if you're a programmer, the name of each file in your program should describe what the code does. If the code diagonalizes matrices, the file should be called something like MatrixDiagonalizer.cpp. If the code reads input from bank tellers, it should be called something like teller_input.c. Some programming languages even enforce this by requiring a particular file-naming convention; Java requires files to have only one object per file, and the name of the file and the object within it must be the same. (Of course, if your object names aren't very good, you're right back where you started.)

— DJPH

7.7 Make More Directories!

Creating many directories has several advantages:

Create new directories liberally! Make a new directory for every new project you start; make subdirectories within these directories for subtopics. Your home directory should ideally contain nothing but subdirectories. Following are some recommended conventions.

If you're a programmer, create a new directory for each project. In the project directory, create a directory called src for source files, a directory called doc or man for documentation, a directory called obj for object files, a directory called rel for the current working version (or almost-working version) of the program, a directory called test for test files and results, and so on. If the program is large, your src and obj directories should also be split into different subdirectories, each containing different parts of the project (or perhaps the subdirectory for each part of the project should have its own src and obj directories).

Many users save all of their mail in one directory (often called Mail or Maildir, depending on your mail system), which is then divided into subdirectories by topic. I use a variation of this scheme; I keep general mail in my Mail directory, but I save correspondence about particular projects with the project itself. For example, my Power Tools mail is shelved with the source code for this article.

— ML

7.8 Making Directories Made Easier

Earlier we told you that you should have lots of directories. Experienced Unix users are creating new directories all the time. How do you make a directory?

It's easy. Use the mkdir command, followed by the name of your new directory:

% mkdir  directory 

This creates the new directory you want. It doesn't necessarily have to be in your current directory. For example:

% cd /home/los/mikel
% mkdir /src/books/power/articles/files

The only requirements are:

What if the parent directory doesn't already exist? Assume, for example, that /src/books already exists, but the power and articles directories do not. You can make these "by hand," or on many Unix systems you can add the -p (parents) option:

% mkdir -p /src/books/power/articles/files

This tells mkdir to create all the intermediate directories that are needed. So the previous command creates three directories:

/src/books/power
/src/books/power/articles
/src/books/power/articles/files

If your mkdir doesn't have -p, you can use history substitution :

% mkdir /src/books/power
% !!/articles
mkdir /src/books/power/articles
% !!/files
mkdir /src/books/power/articles/files

On some mkdirs, you can also supply the file protection mode to be assigned to the directory. (By default, the file protection mode is derived from your umask.) To do so, use the -m option. For example:

% mkdir -m 755 /src/books/power/articles/files

This creates the directory with access mode 755, which allows the owner to do anything with the directory. Note that this must be a numeric mode.

— ML

CONTENTS