-1

Given:

/usr/local/bin/cmake
/usr/bin/cmake
$ cmake # runs /usr/bin/cmake

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

Why this, and how do I make the shell run the executable /usr/local/bin/cmake when I type cmake (without aliases and the like)?

2 Answers2

3

The problem was revealed by running

$ type -f cmake
cmake is hashed (/usr/bin/cmake)

And clearing the bash hash with

hash -d cmake

After this, cmake was interpreted as expected.

3

At some earlier point during the same shell session, you have used cmake and that executable was found in /usr/bin.

You then installed another cmake executable in /usr/local/bin.

The bash shell caches the first location that it finds for any external command that you use, which means it doesn't have to do an expensive search for the executable the next time you use the same command. The downside of this is that it won't bother to look again when you, later, install another executable by the same name, even if it's done in a directory that occurs earlier in $PATH than the original location.

The solution to this issue is to empty the cached locations of executables that bash keeps. This is done with hash -r (rehash in the zsh shell). To only forget the location of the cmake executable, use hash -d cmake (unhash cmake in the zsh shell).


An earlier version of this question additionally wondered why the two commands type cmake and which cmake gave different results, where which cmake appeared to give the expected result (/usr/local/bin/cmake) while type cmake appeared to give the wrong result (/usr/bin/cmake).

The answer to that is that type is a built-in command in bash that will use the same cached locations of commands that the shell uses, and that which is not a built-in command and will therefore not be able to use those cached locations of executables.

In this case, which gave the expected result because it did a search for cmake in your $PATH, but it was in fact the wrong result, since running cmake on the command line would in fact not pick it up from /usr/local/bin (due to the caching, which which would be unaware of).

A summary of the history of which, and the pitfalls of using it, is found here: Why not use "which"? What to use then?

Kusalananda
  • 333,661