## 27.6. Controlling Shell Command Searches

Your search path (Section 35.6, Section 35.7) controls what directories -- and in what order -- the shell searches for external (Section 1.9) commands. You can set a search path that takes effect every time you log in by editing your shell setup file (Section 3.3). You might also want to change the path temporarily. Most shells also keep quick-reference lists of command locations that bypass the search path, so you'll want to know how to manage these.

Changing the path set when you log in is simple: just add the new directory to the appropriate line in your shell's startup files (Section 3.3). It's not recommended to redefine the path completely, though, as some packages rely on their PATH being set correctly. Usually, it is best simply to add the new directory's absolute path (Section 31.2) to the end of the existing PATH variable:

>     PATH=$PATH:$HOME/bin      zsh, sh, ksh, bash
>     set path=($path ~/bin)    zsh (omit the set), csh, tcsh

> NOTE: If you're configuring the superuser (root) account, be careful about using a path set by the parent process (through `$PATH` or `$path`). This path can be used in su shells, giving you part or all the path of the user you su'ed from! Also watch out for a path set by a global setup file like /etc/profile: if it's modified for other users and an insecure version of a system command is added, it could affect the superuser in unexpected ways.

> Of course, there's the opposite danger: forgetting to update the superuser's path because you assume that changing the global path will do the job for root too. My advice is to think about it and decide what's best for your system.

For Bourne-type shells, load the updated PATH by typing a command like:

>     $ .' .profile              sh
>     $ .' .bash_profile         bash

For the C shell, type one of these commands, depending on which file you changed:

>     % source' .cshrc
>     % source' .tcshrc
>     % source' .login

Sometimes you'll want to change the path in just your current shell, though, which is as easy as modifying any other shell or environment variable. Let's assume that for the current session, you want to be able to execute commands being tested before deployment, and that those commands are in your $HOME/someprog/bin directory. Simply add that directory to the front of your existing path:

>     $ PATH=$HOME/someprog/bin:$PATH               Bourne shells
>     $ export PATH

>     $ export PATH=$HOME/someprog/bin:$PATH        bash, ksh

>     % set path=(~/xxx/alpha-test $path)           C shells

Searching the path (Section 27.6) takes time, especially if it's long or if some filesytems are slow or mounted by a slow network link. Most shells have shortcuts to help them remember the locations of commands.

When the C shell starts, it builds a hash table of all the commands in its path: each command name and its absolute pathname. So, after you start a csh running, if new programs are added to directories along the path, you need to use the shell's rehash command to rebuild its hash table. (The hash table is internal. If you have multiple csh shells running -- say, in multiple windows -- type rehash in each one.)

In bash, the command location is automatically stored the first time you use it. This means you don't need a rehash-type command. If a program is moved to a new directory while bash is running, however, you'll need to use the internal command hash -r to make bash "forget" the old location.

> NOTE: Running hash -r causes bash to forget all of its hashed commands, but you may also invoke it with the name of a specific command whose hash should be forgotten:

> >     $ hash -r command

The Korn shell uses tracked aliases to speed up command locating. When it is turned on with `set -o trackall`, every time that ksh finds a new command by doing a path search, it creates an alias for the command name whose value is the full pathname. In ksh88, you can turn alias tracking on and off, and you can mark a command to have an alias defined for it the first time it's executed by using:

>     $ alias -t COMMAND

In ksh93, even though you can run the command `set +o trackall`, which turns off alias tracking in ksh88, the shell ignores the command, and alias tracking is always in effect.

All tracked aliases are cleared when a new value is assigned to the PATH variable. If all you wish to do is remove tracked aliases, use `PATH=$PATH`.

As you can see, shells' command tracking varies! Check your shell's manual page.

--JP and SJC

Copyright © 2003 O'Reilly & Associates. All rights reserved.