- This Samsung phone is the model most people should buy (and it's not a flagship)
- The 50+ best Black Friday Walmart deals 2024: Early sales live now
- How to Dockerize WordPress | Docker
- The smartwatch with the best battery life I've tested is also one of the cheapest
- One of the most immersive portable speakers I've tested is not made by Sony or Bose
Hashing out the hash command on Linux
When you type “hash” on a Linux system, you could get one of two very different responses depending on the shell you are using.
If you are using bash or a related shell such as ksh, you should see a list of the commands that you have used since your terminal session began, sometimes with a count of how many times each command was used. This can be more useful than using the history command if you just want to see your very recent command activity, but the hash command is not a single executable. Instead, it relies on your shell.
hash in bash
Here’s an example of the hash command run in bash:
$ hash hits command 1 /usr/bin/who 1 /usr/bin/vi 1 /usr/bin/man 2 /usr/bin/ls 1 /usr/bin/clear 3 /usr/bin/cat 3 /usr/bin/ps
For bash, the hash command is a built-in. It’s not a separate executable, but a command built into the shell. Some commands—like pwd and echo—don’t get captured in the hash output. You’ll get the same result with this command:
$ builtin hash “$@” hits command 1 /usr/bin/who 1 /usr/bin/vi 1 /usr/bin/man 2 /usr/bin/ls 1 /usr/bin/clear 3 /usr/bin/cat 3 /usr/bin/ps
I found the command shown above in the /usr/bin/hash script on my Fedora system. It’s an /usr/bin/sh script that looks like this:
$ cat /usr/bin/hash #!/usr/bin/sh builtin hash “$@”
If I run this script, I get no output:
$ /usr/bin/hash $ <== no output
Why? Because the script starts a new shell, and no commands have been run in that shell so the hash command has nothing to report. Source the script using “.”, on the other hand, and you’ll get a very different response.
$ . /usr/bin/hash Hits command 1 /usr/bin/who 1 /usr/bin/vi 1 /usr/bin/man 2 /usr/bin/ls 1 /usr/bin/clear 3 /usr/bin/cat 3 /usr/bin/ps
hash in ksh
For ksh, typing “hash” will also display a list of the commands you’ve run in the current session, but without the “Hits” column. Instead, it displays the commands used and the executables in a name=path format. This helps to clarify the reason why the shells are collecting this information in the first place. If the shell has to look down your search path to find the executables for all the commands you use, it helps to “remember” where those executables are located so that it doesn’t have to search your path each time you use the commands.
$ hash bash=/usr/bin/bash cat=/usr/bin/cat column=/usr/bin/column date=/usr/bin/date ls=/usr/bin/ls man=/usr/bin/man ps=/usr/bin/ps
For ksh, hash appears to be an alias:
$ alias | grep hash hash=’alias -t —‘
Running the command associated with the alias should yield the same output:
$ alias -t — bash=/usr/bin/bash cat=/usr/bin/cat column=/usr/bin/column date=/usr/bin/date ls=/usr/bin/ls man=/usr/bin/man ps=/usr/bin/ps
hash in zsh
The hash command in some other shells, like zsh, will provide a very different response. Instead of reporting on the current shell’s command history, it will show you a lengthy list of commands and their file system locations. To see how long the list of remembered locations is, use a command like this:
shs@dragonfly ~ % hash | wc -l 2753
To view the list, you will probably want to pipe the command output to the more command.
shs@dragonfly ~ % hash | more .keepme=/home/linuxbrew/.linuxbrew/bin/.keepme 7z=/usr/bin/7z 7za=/usr/bin/7za AtomicParsley=/usr/bin/AtomicParsley BoD_meeting=/home/shs/bin/BoD_meeting EZscript=/home/shs/bin/EZscript Mail=/usr/bin/Mail ModemManager=/usr/sbin/ModemManager NetworkManager=/usr/sbin/NetworkManager VBoxClient=/usr/bin/VBoxClient VBoxClient-all=/usr/bin/VBoxClient-all VBoxControl=/usr/bin/VBoxControl
In this case, commands included in the output are not restricted to those you have run.
Notice that the shell is not just keeping track of system commands, but also records the locations of scripts you have added in your home directory. When you run a new script, it will be added to your hash output and be visible the next time you start your shell.
shs@dragonfly ~ % hash | grep shs | head -10 BoD_meeting=/home/shs/bin/BoD_meeting EZscript=/home/shs/bin/EZscript about=/home/shs/bin/about append=/home/shs/bin/append backups.log=/home/shs/bin/backups.log bash.pg=/home/shs/bin/bash.pg bigfile=/home/shs/bin/bigfile bigfile2=/home/shs/bin/bigfile2 calcPower=/home/shs/bin/calcPower newscript=/home/shs/bin/newscript
Wrap-Up
The hash command’s response depends on the shell you are using and how it maintains its references to commands you run and the executables on your system. The primary purpose in keeping track of commands is to speed response time by reducing the time required to locate them.
Copyright © 2022 IDG Communications, Inc.