Search Paths of Command Directories
A search path is a sequence of directories where the shell looks for commands to execute. Directories usually contain normal files, but can also contain executable files (either programs or commands). Without a search path, you could not do any real work, since the shell would never find the editor, the ls command, and other indispensable programs. If you write your own programs and shell scripts, or if you use new, specialized, or non-standard commands, you will need to know how to modify your search path. This article explains how to do this.
The C Shell and Environment Path Variables
By default, the C shell searches the directories, /usr/ucb, /bin and /usr/bin, and finally the current directory, ``.'' (dot). The search path is contained in the C shell's path variable. Like all C shell variables, it can be referenced by placing a dollar sign in front of a name. For instance, your current search path can be printed with
% echo $path
The search path is also a component of the environment, which is passed to every process from the process that created it. This means, for instance, that all your shell commands inherit the search path from your shell. You can print your shell's PATH environment variable with
% printenv PATH
The C shell's path variable has spaces between directories, while the PATH environment variable has colons instead. If you change either one of path or PATH, the other is automatically updated to reflect the change.
If you want to use a program in a certain directory (something in /usr/usc/bin, for example), you could set your search path as follows:
% set path = (/usr/usc/bin $path)
This will reset the C shell's path variable by prepending /usr/usc/bin to the previously defined search path. It will also make a corresponding change to the PATH environment variable. Afterwards, you would be able to use any program in /usr/usc/bin, but only for the current login session. In fact, if there were a vi command in /usr/usc/bin, and another in /usr/ucb, the one in /usr/usc/bin would take precedence, because directories are searched in the order they appear in the search path. Setting paths as in this example is recommended primarily for interactive use.
Setting Your Search Path Automatically
You may set your search path automatically each time you log in, by placing the appropriate set path command in your .login file. To learn more about the .login file, type help .login. Here is a sample command line to set a non-standard search path:
set path=(/usr/ucb /bin /usr/bin /usr/usc/bin .)
Make sure there is a space before the period, and spaces between each path element. You may want to place /usr/usc/bin in front of the other directories, if you want it to be searched first.
The above line could have been placed in your .cshrc file, with the effect that your path would be set each time a new shell is started up. A new shell is typically created for an editor escape, or for the execution of a shell script.
Search Paths Containing User Directories
The C shell offers an extremely useful metacharacter, ~ (tilde) which lends portability to shell scripts and commands. It provides a convenient and reliable way to abbreviate the full path name of an account's home directory, which is especially useful when the full pathname changes as the result of a system administrator's having moved the account. When it appears alone, the tilde expands to the full pathname of your home directory. When it appears in front of a name, it expands to the full pathname of that account name.
Suppose you have a directory of programs you have written, named mybin, in your home directory. You could get the shell to search mybin first with the line,
set path=(~/mybin /usr/ucb /bin /usr/bin .)
If there is a directory of programs somewhere on the system, say the directory, bin, in the account, eecs, then you could add that directory to your search path with the command
set path = (~eecs/bin ~/mybin /usr/ucb /bin /usr/bin .)
You might wish to place a special directory first in the list because it contains preferred versions of commands. Suppose now that you add a totally new program to ~/mybin, and then change out of that directory and try to use the new program. The C shell will say ``Command not found'' and will do so until you issue the rehash command. This is because the C shell only knows about commands that it keeps in a specially optimized list of commands called a hash table.
The Search Path Hash Table
A hash table, in this context, is a list of commands together with in indication of where they are found, that can be searched very efficiently. It resides in memory internal to the C shell, is created at login, and is remade whenever you reset your path variable or issue the rehash command. As a result, when new commands are added to one of the command directories in your search path during your login session, they will not be noticed by your shell until the internal hash table has been remade.
The hash table is made for all directories in the path except the current directory, ``.'', since it changes so often. Consequently, searching your current directory is not done very efficiently. If you put the current directory first in your path and most of the commands you type do not reside there, you may end up needlessly waiting for your current directory to be searched for most commands. This is one reason many people prefer to make ``.'' the last component of the search path.
On the other hand, if you are developing alternate versions of system commands in your current directory and want them to be found instead of the standard versions, you may want to make ``.'' one of the first components of your path. Since this causes system programs to start up a bit slower, instead you may want to get in the habit of prepending ``./'' to commands you want from the current directory. For example, ./print would only execute the print command (if any) found in the current directory.
If the path is set in the .login file, it is done once at login, and passed to subshells (for shell scripts or editor escapes) by means of the PATH environment variable. If the search path is set in the .cshrc file, the path is reset every time a new shell is started up. Although the second method may seem less efficient, it has the advantage that if you execute commands over the network, the path setting in your remote .cshrc file is used instead of your remote .login file, since the network shell only reads .cshrc when it starts up.