Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

In case of shell-builtins (eg type itself):

$ type type
type is a shell builtin

$ which type
<Doesn't return anything since it's a shell builtin, silently exits>

In case of commands (normally) (eg python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

In case of which (which is a command located at /usr/bin/which)

$ type which
which is hashed (/usr/bin/which)
$ which which
/usr/bin/which

Why does type which say that which is hashed? What is the significance of which being hashed and what does it actually mean?

share|improve this question

1 Answer 1

up vote 19 down vote accepted

You likely have a long PATH set and, to find an executable, the shell needs to search the path. To avoid that time consuming process every time that you want to run a program, the shell may keep a list of programs that it has already found. That list is called a "hash." When the shell says that which is hashed, it means that it has already done the PATH search and found which and saved its location in the hash.

man bash explains it as follows:

Bash uses a hash table to remember the full pathnames of executable files (see hash under SHELL BUILTIN COMMANDS below). A full search of the directories in PATH is performed only if the command is not found in the hash table.

While the hash normally speeds up shell operations, there is one case where it causes problems. If you update your system and, as a result, some executable moves to a new location, the shell may get confused. The solution is to run hash -r which causes the shell to forget all the hashed locations and search the PATH from scratch.

Why are some executables missing from the hash?

An executable is not placed in the hash until after you execute at least once. Observe:

$ type python
python is /usr/bin/python
$ python --version
Python 2.7.3
$ type python
python is hashed (/usr/bin/python)

python is hashed only after it has been executed.

How to examine what is in bash's hash

The contents of the hash are available in the bash array BASH_CMDS. You can see what is in it with the command declare -p BASH_CMDS. When a new shell or subshell is opened, the hash is empty. Commands are added one by one as they are used. From a newly opened shell, observe:

$ declare -p BASH_CMDS
declare -A BASH_CMDS='()'
$ which which
/bin/which
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" )'
$ python --version
Python 2.7.3
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" [python]="/usr/bin/python" )'
share|improve this answer
    
+1, pretty good explanation. But why for which and not for python? –  i08in Apr 11 at 19:10
    
@Jobin See updated answer. –  John1024 Apr 11 at 19:53
    
It looks like the hash persists only till the time we do not exit the shell. Once we restart the terminal, it doesn't say that the command is hashed. –  Aditya Apr 12 at 9:24
    
@Aditya Yes. I added a section on that to the answer. –  John1024 Apr 12 at 17:41

Your Answer

 
discard

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.