hash
is a bash built-in command. The hash table is a feature of bash
that prevents it from having to search $PATH
every time you type a command by caching the results in memory. The table gets cleared on events that obviously invalidate the results (such as modifying $PATH
)
The hash
command is just how you interact with that system (for whichever reason you feel you need to).
Some use cases:
Like you saw it prints out how many times you hit which commands if you type it with no arguments. This might tell you which commands you use most often.
You can also use it to remember executables in non-standard locations.
Example:
[root@policyServer ~]# hash -p /lol-wut/whoami whoami
[root@policyServer ~]# whoami
Not what you’re thinking
[root@policyServer ~]# which whoami
/usr/bin/whoami
[root@policyServer ~]# /usr/bin/whoami
root
[root@policyServer ~]#
Which might be useful if you just have a single executable in a directory outside of $PATH
that you want to run by just type the name instead of including everything in that directory (which would be the effect if you added it to $PATH
).
An alias can usually do this as well, though and since you're modifying the current shell's behavior, it isn't mapped in programs you kick off. A symlink to the lone executable is probably the preferable option here. hash
is one way of doing it.
- You can use it to un-remember file paths. This is useful if a new executable pops up in an earlier
PATH
directory or gets mv
'd to somewhere else and you want to force bash to go out and find it again instead of the last place it remembers finding it.
Example:
[root@policyServer ~]# hash
hits command
1 /bin/ls
[root@policyServer ~]# cp /bin/ls /lol-wut
[root@policyServer ~]# hash
hits command
1 /bin/cp
1 /bin/ls
[root@policyServer ~]# hash -d ls
[root@policyServer ~]# ls
default.ldif newDIT.ldif notes.txt users.ldif
[root@policyServer ~]# hash
hits command
1 /bin/cp
1 /lol-wut/ls
[root@policyServer ~]#
The cp
command caused a new version of the ls
executable to show up earlier in my $PATH
but didn't trigger a purge of the hash table. I used hash -d
to selectively purge the entry for ls
from the hash table. Bash was then forced to look through $PATH
again and when it did, it found it in the newer location (earlier in $PATH than it was running before).
You can selectively invoke this "find new location of executable from $PATH
" behavior, though:
[root@policyServer ~]# hash
hits command
1 /bin/ls
[root@policyServer ~]# hash ls
[root@policyServer ~]# hash
hits command
0 /lol-wut/ls
[root@policyServer ~]#
You'd mostly just want to do this if you wanted something out of the hash table and weren't 100% that you could logout and then back in successfully, or you wanted to preserve some modifications you've made to your shell.
To get rid of stale mappings, you can also do hash -r
(or export PATH=$PATH
) which effectively just purges bash's entire hash table.
There are lots of little situations like that. I don't know if I'd call it one of the "most useful" commands but it does have some use cases.
hash
command internally uses a hash table to store the mappings. http://en.wikipedia.org/wiki/Hash_table – jlliagre Aug 08 '13 at 20:39hash
is notbash
specific, the command originated in the Bourne shell in SVR2 (though the feature of hashing paths of commands comes fromcsh
before that) and is found in all Bourne-like and POSIX shells. – Stéphane Chazelas Aug 08 '13 at 21:34export PATH=$PATH
to clear the table,hash -r
should suffice. – ravron Jan 04 '16 at 18:52hash -r
or you'll get the old version because $PATH didn't change and so Bash doesn't realize it could load the same program from an earlier (higher priority) directory. See http://conda.pydata.org/docs/troubleshooting.html#resolution-reactivate-the-environment-or-run-hash-r-in-bash-or-rehash-in-zsh for details. – John Zwinck Jan 19 '17 at 04:26hash
command and bash's behavior when a program is no longer in the cache. For example if I delete a program that previously got found in thePATH
(I deleted it because I wanted a different program with the same name to be used),bash
unhelpfully says "bash: \path\to\deleted-program: No such file or directory" instead of just searching thePATH
for it again. Then I have to remember/lookup the stupid command to reset the hash (andman hash
further complicates things by bringing up docs for some database programming API). – Michael Burr Jan 25 '18 at 23:04hash
has anything to do with searching aPATH
? What do I care thatbash
uses a hash table (or a sorted list or just the file system) to store these things? In fact, I'd likebash
to behave as much as possible as if it uses the file system to store this information sincePATH
is a description of where on the file systembash
should look for programs. If bash needs to optimize that, fine, but it should be resilient to breaks and fixing problems that I do notice shouldn't require tedious research. Sorry for the rant. – Michael Burr Jan 25 '18 at 23:13$PATH
on every invocation. Imagine a scenario where you have multiple slow NFS mounts in$PATH
then storing the location of executables in memory prevents you from seeing a hug lag when you type a simplels -l
out. – Bratchley Jan 29 '18 at 14:21hash
command is a good one. The discoverability is terrible -man hash
gives you no good info on it,hash --help
is not very helpful, and why would I think that a command namedhash
has anything to do withPATH
problems in the first place? The behavior ofbash
when a hash-match no longer works is terrible - why not just search thePATH
again, or at least mention that thehash
command might be of use? Anyway, I'm sorry for the rant - especially since it isn't really directed at you or your answer. – Michael Burr Jan 30 '18 at 17:11hash
isn't really something you use that often. In the ~15 years I've been using Unix/Linux, I've literally never used it outside of when I first learned about it in college and then again when I wrote this answer. You can't possibly document every single part of the system and the hash table really is just some random part of the system. – Bratchley Jan 31 '18 at 15:05hash
does this answer actually comes up in a google search (when I searched forhash command
it was #1) which is the most common MO nowadays anyways. – Bratchley Jan 31 '18 at 15:09