In an earlier article titled “How to set the PATH variable in Linux” we discussed placing executable scripts in your PATH. This makes it convenient to invoke them by name only, instead of full path (i.e. myscript.sh instead of /path/to/myscript.sh). Searching PATH can become cumbersome if you have a lot of directories and executables. The bash shell keeps a hash table for all the commands run in your current shell. It uses this table to quickly look up the full path of an executable without searching PATH. In this article we will discuss how to manipulate this table using the bash builtin hash command.

Bash searches each element of $PATH for a directory containing an executable file by that name. Bash uses a hash table to remember the full pathnames of executable files to avoid multiple PATH searches. A full search of the directories in $PATH is performed only if the command is not found in the hash table.

-Bash Manual

Listing Your Bash Hash Table

You can display the hash table for the current shell by invoking hash without any arguments. In this view the hash outputs the number of hits (calls for that command) and the command with it’s path.

Screenshot of terminal using the hash command to list bash hash table

You can think of the sum of all hits as the number of saved searches through $PATH.

Use the -l option to display the hash table in a format that is usable as input.

Screenshot of terminal using the hash command to list bash hash table in a long format to be used as input

You can also print the remembered location of a specific name by using the -t option.

[[email protected] ~]$ hash -t putorius
 /home/savona/.local/bin/putorius

Optionally, you can provide several names separated by spaces.

[[email protected] ~]$ hash -t putorius chmod
 putorius    /home/savona/.local/bin/putorius
 chmod    /usr/bin/chmod

Adding a Command Path and Name to the Hash Table

This is where the hash command becomes interesting. You can add items to the hash table to be reused in the shell. It is important to note that the hash table only exists in the current shell. If you open a new shell, bash creates a new hash table.

[[email protected] ~]$ hash
 hash: hash table empty

As soon as you run your first command bash starts to generate the hash table.

[[email protected] ~]$ mkdir /tmp/test

[[email protected] ~]$ hash
 hits    command
    1    /usr/bin/mkdir

You can manually add a command to the hash table using the -p option followed by the path and then the name. In this manner the hash table can be used similar to an alias. In the example below we add the /tmp/test/hello-world.sh script to the hash table with the name hello.

[[email protected] ~]$ hash -p /tmp/test/hello-world.sh hello

[[email protected] ~]$ hash -l
 builtin hash -p /usr/bin/which which
 builtin hash -p /usr/bin/mkdir mkdir
 builtin hash -p /usr/bin/chmod chmod
 builtin hash -p /tmp/test/hello-world.sh hello
 builtin hash -p /usr/bin/vim vim

Now that the name hello is mapped to the /tmp/test/hello-world.sh script in the hash table, we can invoke it by name only.

[[email protected] ~]$ hello
 Hello World!

Bash checks the hash table for the name to find the executable. There is no need to put the script in your PATH, unless you want it to be available in all new shells.

Deleting an Item from the Hash Table

You can delete or “forget” a remembered location of a command by using the -d option followed by the name.

[[email protected] ~]$ hash -l
 builtin hash -p /usr/bin/which which
 builtin hash -p /tmp/test/hello-world.sh hello

[[email protected] ~]$ hash -d hello

[[email protected] ~]$ hash -l
 builtin hash -p /usr/bin/which which

Clearing the Hash Table

You can also clear the hash table completely by using the -r option.

[[email protected] ~]$ hash
 hits    command
    2    /usr/bin/which
    1    /var/tmp/go
    2    /usr/bin/chmod
    1    /usr/bin/neofetch
    1    /usr/bin/vim
    3    /home/savona/.local/bin/putorius
    2    /usr/bin/clear
    2    /usr/bin/logger
    1    /usr/bin/rm

 [[email protected] ~]$ hash -r

 [[email protected] ~]$ hash
 hash: hash table empty

Conclusion

The hash command is a Bash builtin command that can be used to manipulate the command hash table. In this article we explored listing items in the hash table, adding commands to the hash table and deleting commands from the hash table. We also discussed how we can use the hash table to simulate and alias. The hash table is not something normally used in day to day operations. However, I do know some developers who use it often. As a system administrator it can be a useful tool in certain situations.

animated gif showing how the linux hash command works to manipulate the command hash table

Resources and Links