MacOS – Terminal: command overridden via shell script in /usr/local/bin not executed unless called directly

bashcommand linemacossshterminal

I've created a shell script wrapping ssh to change my terminal background when connecting to a server following one of the many examples on this site and stackexchange.

11:22 ~  $ echo $PATH
/opt/local/bin:/opt/local/sbin:/Volumes/Macintosh HD/Users/robertson/bin/android-sdk-macosx/platforms:/Volumes/Macintosh HD/Users/robertson/bin/android-sdk-macosx/tools:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/git/bin
11:22 ~  $ which ssh
/usr/local/bin/ssh
11:22 ~  $ whereis ssh
/usr/bin/ssh

As you can see, which ssh does correctly find the script I placed in /usr/local/bin, however whereis ssh does not, and when I run ssh user@example.com, I still get the system ssh without executing my wrapper. I'm forced to call it directly via /usr/local/bin/ssh user@example.com to get the color change.

Any idea what's missing here?

Best Answer

Order of execution is based on PATH order - locations put first are searched first, if match is found it is executed, HOWEVER, programs mapping are cached so you need to refresh the cache before changes will take place (if you've used that app before). See http://www.thegeekstuff.com/2010/08/bash-shell-builtin-commands/ (point 3.):

hash command maintains a hash table, which has the used command’s path names. When you execute a command, it searches for a command in the variable $PATH. But if the command is available in the hash table, it picks up from there and executes it. Hash table maintains the number of hits encountered for each commands used so far in that shell.

and

You can delete a particular command from a hash table using -d option, and -r option to reset the complete hash table.

Sidenote: maybe try to create alias instead of wrapper?