Why the command line does not respect the PATH order on OS X

consolessh

I added an ssh command inside ~/bin/ssh and modified the PATH to include it, before other paths.

When I do run which ssh it will respond with ~/bin/ssh but when I do run ssh it will just execute the /usr/bin/ssh instead.

I have no aliases for ssh.

What's the reason and how can I fix it?

Best Answer

Do not use which, use type. The which command in the default shell (bash) is an external utility which doesn't know about aliases and functions. On the other hand, type is an internal utility which will tell you whether its argument is an alias, a function, a built-in utility or an external command.

The which command is mentioned in tutorials and manuals only for historical reasons — 30 years ago the type command didn't exist everywhere, and some people have been slow to adapt.

For more details, including a discussion of historical and current shells, see Why not use “which”? What to use then?

$ type cp
cp is aliased to `cp -i'
$ type mkcd
mkcd is a function
mkcd ()
{
…
}
$ type type
type is a shell builtin
$ type cat
cat is /bin/cat

In zsh, it's ok to use which: zsh has both type and which as built-in commands.

Also note that if you just installed or removed a program, the shell may have memorized its old location. For example, if you just installed your own version of a program in a directory that is ahead of the system directories in $PATH, the shell may keep invoking the program that came with the system. This is only an issue in shells that were already running at the time of the installation or removal. To refresh the shell's memory with current data, run the command hash -r or hash COMMANDNAME.