Csh Command Search Path
A search path is the sequence of directories in which the shell looks for commands to execute. Although some directories only contain regular files, many directories also contain executable files (either programs or commands). Without a search path, you could not do any real work, since the shell could never find editor programs, the "ls" command, and other programs that are indispensable to your work routine. 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 writeup explains how to accomplish this.
By default, the C shell searches /usr/ucb, /bin, /usr/bin, /usr/local/bin, the current directory (.), /usr/new, and /usr/hosts. It used to be that the current directory was searched first, but this was changed because of efficiency considerations that will be explained below.
The search path is contained in the C shell "path" variable. Like all C shell variables, it can be referenced by placing a dollar sign in front of a name. If you want to know your current search path, you can enter the command below to have it displayed on your terminal screen
The search path is also a component of the environment, which is passed from process to process, independent from the shell. You can view your environment's PATH variable by entering
The character between each directory in the C shell's $path variable is a space, while the PATH environment variable has colons instead. The environment's PATH exists independently, so it can be read by programs that are not related to the shell.
If you want to use a program in a particular directory that is not in your regular search path (something in /usr/fred, for example), you could add to the search path by entering the following command:
set path = (/usr/fred $path)
This will reset the C shell's $path variable by prepending /usr/fred to the previously defined search path. It will also make a corresponding change to the PATH environment variable. Once you have entered the above command, you should be able to use programs in /usr/fred, but only for the current login session. In fact, if there were a "vi" command in /usr/fred, and another in /usr/ucb, the one in /usr/fred would take precedence.
Directories are searched in the order they appear in the search path. Setting paths with "$path" is recommended primarily for interactive use.
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 dotlogin".) Here is a sample of a command line that you might put in your .login file to set a non-standard search path:
set path = (/usr/ucb /bin /usr/bin /usr/new .)
Make sure that there is a space before the period, and spaces between each path element. If you want /usr/new to be searched first, you may want to place it in front of the other directories. However, this is somewhat risky, as it will always give you new (experimental) versions of commands, rather than supported versions.
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. New shells are typically created for an editor escape, or for the execution of a shell script.
The C shell uses an extremely useful metacharacter, the tilde (~), which lends portability to shell scripts and commands. 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," branching from your home directory. You could get the shell to search "mybin" first by inserting the line
set path = (~/mybin /usr/ucb /bin /usr/bin .)
If there is a directory of programs somewhere in the system, say the directory "bin" in the account "eecs", then you could add that directory to your search path with this command:
set path = (~eecs/bin /usr/ucb /bin /usr/bin .)
You might wish to place a special directory first in the list because you use those commands most frequently, or because the directory contains preferred versions of commands.
Now if 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." This is because the C shell keeps a hash table listing all the programs in the search path, for increased efficiency. Until you issue the "rehash" command, which remakes the hash table, the C shell will not be able to find the new program.
A hash table, in this context, is a list of programs, with an indication of where they are found; it resides in memory, internal to the C shell. The hash table is made for all directories in the path except the current directory (.), which can always change. The table is created at login, and remade whenever you set your path.
The shell consults its internal hash table before it does a linear search of the current directory. This allows commonly used system commands to start up quickly. If you use shell scripts or programs in your own directory which have the same names as system programs, then you may want to have the current directory searched first.
set path = (. /usr/ucb /bin /usr/bin /usr/new)
Searching the current directory first will cause system programs to start up somewhat slowly, but it may be convenient for program development. An alternative would be to get in the habit of typing "./print" (for example) every time you test out your customized "print" command.
If the search 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 from the environment. If the path is set in the .cshrc file, the $path is reset every time a new shell is started up.
When deciding whether to put a command in .cshrc or .login, it is important to understand that the .login file (which is executed when you login) is executed AFTER the .cshrc file. In other words, a 'set path' in your .login will replace or modify one made in your .cshrc.