Por que 'digita qual' diz que 'qual é hash'?

23

No caso de built-in de shell (por exemplo, type ):

$ type type
type is a shell builtin

$ which type
<Doesn't return anything since it's a shell builtin, silently exits>

No caso de comandos (normalmente) (por exemplo, python ):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

No caso de which (que é um comando localizado em /usr/bin/which )

$ type which
which is hashed (/usr/bin/which)
$ which which
/usr/bin/which

Por que type which diz que which is hashed ? Qual é o significado de which ser hashed e o que isso realmente significa?

    
por Aditya 11.04.2014 / 20:50

1 resposta

30

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" )'
    
por John1024 11.04.2014 / 20:57