-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)?

11
  • 3
    Related: Why not use "which"? What to use then?
    – Kusalananda
    Nov 29, 2019 at 13:17
  • 2
    If that is your path, the cmake in /usr/local/bin should take precedence. What is the output of which cmake and type -a cmake?
    – user232326
    Nov 29, 2019 at 13:31
  • 2
    okay, I cleared the bash hash, the problem went away
    – user907323
    Nov 29, 2019 at 13:37
  • 1
    @schily I don't think I ever have recommended which. If I did, let me know where and I'll correct it.
    – Kusalananda
    Nov 29, 2019 at 14:47
  • 1
    @schily That's a canonical question relating to the issues with which.
    – Kusalananda
    Nov 29, 2019 at 15:10

2 Answers 2

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?

Not the answer you're looking for? Browse other questions tagged .