Você provavelmente tem um longo conjunto PATH e, para encontrar um executável, o shell precisa pesquisar o caminho. Para evitar esse processo demorado toda vez que você deseja executar um programa, o shell pode manter uma lista de programas que ele já encontrou. Essa lista é chamada de "hash". Quando o shell diz que which
está com hash, significa que ele já fez a pesquisa PATH e encontrou which
e salvou sua localização no hash.
man bash
explica da seguinte forma:
O Bash usa uma tabela de hash para lembrar os nomes completos dos caminhos de arquivos executáveis (veja o hash em SHELL BUILTIN COMMANDS abaixo). Uma pesquisa completa dos diretórios no PATH é executada somente se o comando não é encontrado na tabela de hash.
Enquanto o hash normalmente acelera as operações do shell, há um caso em que isso causa problemas. Se você atualizar seu sistema e, como resultado, alguns movimentos executáveis para um novo local, o shell pode ficar confuso. A solução é executar hash -r
, o que faz com que o shell esqueça todos os locais com hash e pesquise o PATH desde o início.
Por que alguns executáveis estão faltando no hash?
Um executável não é colocado no hash até que você execute pelo menos uma vez. Observe:
$ type python
python is /usr/bin/python
$ python --version
Python 2.7.3
$ type python
python is hashed (/usr/bin/python)
python
é hash somente depois de ter sido executado.
Como examinar o que está no hash do bash
O conteúdo do hash está disponível em bash
array BASH_CMDS
. Você pode ver o que está nele com o comando declare -p BASH_CMDS
. Quando um novo shell ou subshell é aberto, o hash está vazio. Os comandos são adicionados um por um conforme são usados. De uma concha recém-aberta, observe:
$ declare -p BASH_CMDS
declare -A BASH_CMDS='()'
$ which which
/bin/which
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" )'
$ python --version
Python 2.7.3
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" [python]="/usr/bin/python" )'