hash cache in bash

Not funny and obsolete

George Shuklin
OpsOps
2 min readOct 17, 2019

--

Yesterday I’ve learned one more thing from the past I didn’t want to know. I could justify it at the time of invention, but I think it’s obscure, rotten and bringing too much of ‘deep internal world’ of some mundane utility onto users of modern systems.

It’s called ‘executable caching’. When you call some binary for the first time, bash caches the path for that binary. You can see it by calling hash. This is built-in command in bash. It shows you what commands you’ve called, how many times and their paths.

When it breaks?

I tried to use new Ansible in .venv. I sourced .venv/bin/activate, called ansible-playbook (original one, installed in my system), pip-installed new ansible. I checked version: ansible --version was new. I then ran ansible-playbook, and it rejected to work on my playbook, as I always have ‘version lock’ on my playbooks:

It complained I’m still on 2.7. ansible says version is 2.8.something. I run ansible-playbook --version and it said 2.7! With system paths. And ansible said it’s 2.8 and on .venv. which for ansible-playbook said “.venv!”, and PATH was set right (with .venv at front).

Of course, the reason was that call of ansible-playbook after .venv but before running pip install ansible. Bash has cached the location of the ansible-playbook binary and wasn’t intended to search for it again.

They saved few syscalls (premature optimization) and cause big WTF for users.

How to disable it?

into ~/.bashrc.

How to fix it right away? hash -r.

--

--

George Shuklin
OpsOps

I work at Servers.com, most of my stories are about Ansible, Ceph, Python, Openstack and Linux. My hobby is Rust.