I am trying to use a very basic setup pattern here: I have two different installations of a given tool (ocamlc, but that does not really matter). In order to select one tool, I attempt to override the PATH variable by prepending an entry.
% where ocamlc
/home/choeger/ueb/uebb/amsun-integration/Runtime/test_src/../../opam/4.02.3/bin/ocamlc
/home/choeger/.opam/4.02.3/bin/ocamlc
/usr/bin/ocamlc
However, the zsh still uses the older entry:
% ocamlc -v
The OCaml compiler, version 4.02.3
Standard library directory: /home/choeger/.opam/4.02.3/lib/ocaml
(One can see that it uses the second entry because the library directory is hardcoded to that installation)
Bash behaves as expected:
% bash -c "ocamlc -v"
The OCaml compiler, version 4.02.3
Standard library directory: /home/choeger/ueb/uebb/amsun-integration/opam/4.02.3/lib/ocaml
So why does zsh ignore the first PATH entry although it lists it as first element of where
?
edit: In order to verify that zsh does not invoke the same binary, here is another run:
% type -a ocamlc
ocamlc is /home/choeger/ueb/uebb/amsun-integration/tests/pendulum/../../opam/4.02.3/bin/ocamlc
ocamlc is /home/choeger/.opam/4.02.3/bin/ocamlc
ocamlc is /usr/bin/ocamlc
% ocamlc -v
The OCaml compiler, version 4.02.3
Standard library directory: /home/choeger/.opam/4.02.3/lib/ocaml
% /home/choeger/ueb/uebb/amsun-integration/tests/pendulum/../../opam/4.02.3/bin/ocamlc -v
The OCaml compiler, version 4.02.3
Standard library directory: /home/choeger/ueb/uebb/amsun-integration/opam/4.02.3/lib/ocaml
edit2: Here is the setopt output:
% setopt
autocd
autopushd
nobeep
completeinword
correct
extendedglob
extendedhistory
histignorealldups
histignorespace
nohup
interactive
interactivecomments
longlistjobs
monitor
nonomatch
pushdignoredups
shinstdin
zle
%
Config is the grml config found here plus some path variables in the .local file.
By default zsh
hashes locations of commands the first time they are executed. When executing it a second time the hashed path is used. To refresh the hash table run
rehash
or
hash -r
This should happen automatically every time you change PATH
and its main use is, when new executables are added to directories already in PATH
.
Note: the following might be overkill for the specific use case. But it also does solve the issue and might be of interest for slightly different use cases.
If you do not care about the (probably negligible) performance hit, you can disable hashing of commands by disabling the HASH_CMDS
option:
setopt nohashcmds
While zsh
will still be using the hash table, it will not automatically add every command. So, unless a command is entered to the hash table by other means, zsh
will check PATH
for the command every time.
This might still lead to problems, if the option CORRECT
is set. As this does set the hash table in order to provide spelling correction, but will not necessarily refresh it when PATH
changes. In order to refresh the table automatically, you can use the precmd
hook which is executed each time before the prompt is printed.
autoload -Uz add-zsh-hook
auto_rehash () {
rehash
}
add-zsh-hook precmd auto_rehash
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With