I am having some strange behavoir with zsh ( 5.4.2_1 installed with homebrew ) on osx not using the first occurrence of an executable in the path.

Here is the scenario:

echo $PATH returns:


brew is in both




This is confirmed by running which -a brew which returns:


But when I run which brew it returns:


and brew does run /usr/local/bin/brew rather than /usr/local/Cellar/zplug/HEAD-9fdb388/bin/brew

How can this happen when brew is earlier in the path ?

Help appreciated.

  • 7
    rehash and run those again - if it still happens afterwards, edit that in. – Michael Homer Dec 5 '17 at 6:04
  • @MichaelHomer: Yup that's the one. Experience here. – Joshua Dec 5 '17 at 22:23

which -a cmd looks for all regular files named cmd which you have execute permission for in the directories in $path (in addition to aliases, functions, builtins...).

While which cmd returns the command that zsh would run (which is a builtin in zsh like in tcsh but unlike most other shells).

zsh, like most other shells remembers the paths of executables in a hash table so as not to have to look them up in all the directories in $path each time you invoke them.

That hash table (exposed in the $commands associative array in zsh) can be manipulated with the hash command (standard POSIX shell command).

If you have run the brew command (or which/type/whence brew, or used command completion or anything that would have primed that hash/cache) before it was added to /usr/local/Cellar/zplug/HEAD-9fdb388/bin or before /usr/local/Cellar/zplug/HEAD-9fdb388/bin was added to $path, zsh would have remembered its path and stored it as $commands[brew]=/usr/local/bin/brew.

In that case, you can use hash -r (as in the Bourne shell) or rehash (as in csh) to have zsh forget the remembered commands (invalidate that cache), so it can look it up next time and find it in the new location.

  • Thanks - this sorted the problem. Should I be able to echo $command[brew] - I see nothing ? – continuum Dec 5 '17 at 9:33
  • 1
    @continuum, sorry, my bad, that's $commands, not $command. See edit. – Stéphane Chazelas Dec 5 '17 at 9:44

/usr/local/bin/brew is a usually a symbolic link.

So /usr/local/bin/brew and /usr/local/Cellar/zplug/HEAD-9fdb388/bin/brew

are probably the same files.


ls -al /usr/local/bin/brew

to confirm.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.