Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In bash (or any other shell), when you type "firefox" or another command, how does bash point it to its actual location (/usr/bin/firefox)? Also, where is the "catalog" for bash autocomplete?

share|improve this question
up vote 1 down vote accepted

There's a $PATH variable that holds all paths (colon-separated) to lookup for command names. Those folders are checked from the first one to the last one and command is executed when found (so if there are multiple files of that name in different $PATH directories, the first one will be executed).

To view $PATH:

echo $PATH

To check where firefox is:

which firefox
share|improve this answer
If it happens that there are commands with the same name, but in different folders (both in $PATH), you can use which -a firefox to list all of them. On execution, the shell picks the first one. – mpy Mar 1 '13 at 20:02
so how would someone add a program to $path or am I understanding this wrongly? Also, is there an actual file? – agz Mar 5 '13 at 8:50
$PATH folders are looked up when you issue a command. When file is found, it's executed. To "create" a new command, add an executable file of that name to any PATH-ed directory. You can also create a new dir with that file and add the dir to $PATH. – gronostaj Mar 5 '13 at 12:41

bash and other shells and command processors search your PATH directories, looking for an executable file that matches the command name you've typed.

share|improve this answer

The essentials are already given in the other answers. Technically, the shell stores the location of a command in a hash table. In bash you can view this table by the command hash:

$ hash
hits    command
   2    /usr/bin/ldd
   1    /usr/bin/man
   1    /usr/bin/less

You can also modify this hash table, for details I quote the bash man page:

hash [-lr] [-p filename] [-dt] [name]

For each name, the full file name of the command is determined by searching the directories in $PATH and remembered. If the -p option is supplied, no path search is performed, and filename is used as the full file name of the command. The -r option causes the shell to forget all remembered locations. The -d option causes the shell to forget the remembered location of each name. If the -t option is supplied, the full pathname to which each name corresponds is printed. If multiple name arguments are supplied with -t, the name is printed before the hashed full pathname. The -l option causes output to be displayed in a format that may be reused as input. If no arguments are given, or if only -l is supplied, information about remembered commands is printed. The return status is true unless a name is not found or an invalid option is supplied. Here you can see, which commands you already executed in this session.

Other shells can behave differently, in zsh (and I think this was adapted from csh) the shell gathers all command at startup or by invoking rehash. Then you get a complete list of all available commands with hash and you can search e.g. for all variants of diff:

zsh$ hash | grep diff

Again, consult man zshbuiltins for much more details.

share|improve this answer
  1. bash uses the $PATH environment variable to look for programs by word. Paths are separated by :. Your $PATH is most likely something like :/usr/bin:/usr/games:/usr/local/bin:/usr/local/games:, so it finds it in /usr/local/bin. Change your $PATH and try again.
  2. You can change tab completion behavior via the complete builtin. See the "Programmable Completion" of man bash.
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.