Bash can be trash. Even if you?re barely Linux or Bash or fish or zsh (or even Windows) literate, you know that shells should look in your path for stuff. Why then would your command-line friend say something so rude as ?No such file or directory? for something that you absolutely know exists in your path?
(Photo credit: Samantha Garrote)
Introducing the hash builtin
To make things quick as a flash, Bash has tricks. One of them is to use hash to stash the full path of previously executed stuff (e.g., commands, applications) Bash finds in your path. Next time you call a command, Bash does not thrash around your path again and instead slaps down the previously discovered full path. Voil!
Except that sometimes the approach crashes because stuff isn?t where it used to be. Maybe a project reorganized its structure or you moved stuff around or whatever. Then you call a command and get this trash:
$ terraform -vbash: /usr/local/bin/terraform: No such file or directory
The fix is quick enough to give you whiplash: get rid of all the trash that Bash has saved using hash.
$ hash -r
A few more details
If you want to peek at Bash?s hash stash, just type hash without arguments.
$ hashhits command1 /usr/bin/top2 /usr/bin/man1 /usr/bin/grep1 /usr/local/bin/terraform
Problems with hash are easily encountered if you install the same application in multiple places.
For example, look at Terraform above. Bash/hash now says a call to terraform will go to /usr/local/bin. But, imagine you?ve deleted Terraform in /usr/local/bin because you?re building it from source. The make script will install the newly built binary executable at $GOPATH/bin. Calling Terraform after building gives this message:
$ terraform -v-bash: /usr/local/bin/terraform: No such file or directory
The message tips you off to the problem because you can see Bash is looking in all the wrong, um, place.
The simplest thing is to just brashly smash the entire hash Bash cache:
$ hash -r
However, if you have a very long path or a possibly unhealthy attachment to your current hard-earned cache, you can replace a single entry too:
$ hash -p $GOPATH/bin/terraform terraform
Now, the cache shows the new location:
$ hashhits command1 /usr/bin/top2 /usr/bin/man1 /usr/bin/grep1 /Users/sharkey/go/bin/terraform
If Bash gives you some ?no such file or directory? balderdash, remember to smash and slash your trash stash in the hash Bash cache.