Desativar o cache de executáveis ​​do bash no caminho


12

Observe que isso não é uma duplicata. Estou perguntando sobre desativar o cache, não limpá-lo. Se você tiver um cache para limpar, obviamente ele não está desativado.

Nas raras ocasiões em que percebo o cache do bash de coisas que ele encontrou no caminho, não é porque é útil, é porque é muito chato. Um exemplo:

~ dc$ export PATH=$HOME/bin:$PATH
~ dc$ cat bin/which
#!/bin/bash
echo "my which"
~ dc$ which
my which
~ dc$ rm bin/which
~ dc$ which which
-bash: /Users/dc/bin/which: No such file or directory

Em outra concha ...

~ dc$ which which
/usr/bin/which

Tenho certeza de que esse cache fazia sentido nos velhos tempos, quando os discos eram lentos e a memória era cara e limitada e, portanto, você não podia armazenar muito em cache - o armazenamento em cache de um caminho é mais barato do que o armazenamento em cache de todos os blocos de disco necessários para encontrar um comando . Atualmente, porém, não oferece benefícios visíveis e causa mais problemas do que resolve. É uma falha de funcionalidade, prestes a ser um bug.

E nem consigo encontrar uma maneira de desativá-lo. Alguma dica?


1
Os benefícios são visíveis mesmo no caso comum de uma máquina de desktop, se você não tiver tanta RAM que /usr/binpermaneça inteiramente no cache.
Gilles 'SO- stop be evil'

1
@drhyde, desculpe. Marquei esta pergunta como duplicada. Use set +hpara desativar o hash.
Evgeny Vereshchagin

No Nixos, ele desativou o hash em seu bash. Eu acho que, por uma boa razão, devido à maneira de trabalhar do Nixos. No entanto, não tenho certeza se isso é realmente obrigatório para o Nixos. Só estou dizendo que um hash no bash pode trazer problemas em determinadas situações.
Typelogic

Respostas:


12

Você pode simplesmente limpar os executáveis ​​de hash antes que o prompt seja desenhado:

PROMPT_COMMAND='hash -r'

De help hash:

hash: hash [-lr] [-p pathname] [-dt] [name ...]
Remember or display program locations.

Determine and remember the full pathname of each command NAME.  If
no arguments are given, information about remembered commands is displayed.

Options:
  -d                forget the remembered location of each NAME
  -l                display in a format that may be reused as input
  -p pathname       use PATHNAME is the full pathname of NAME
  -r                forget all remembered locations
  -t                print the remembered location of each NAME, preceding
            each location with the corresponding NAME if multiple
            NAMEs are given
Arguments:
  NAME              Each NAME is searched for in $PATH and added to the list
            of remembered commands.

Exit Status:
Returns success unless NAME is not found or an invalid option is given.

1
veja minha resposta sobreset +h
Evgeny Vereshchagin

1
@EvgenyVereshchagin set +hnão é o ideal, como muitos utilitários (por exemplo, instalações de ruby ​​gem) chamam hash, produzindo fluxos de -bash: hash: hashing disabledavisos.
David Moles

Também vejo as mesmas mensagens de aviso em uma ativação do python virtualenv. Mas acho que é inofensivo.
Typelogic

8

Você pode forçar o bash a fazer uma nova pesquisa de caminho, caso um comando na tabela de hash não exista mais.

shopt -s checkhash

Da página de manual do bash:

checkhash

    Se definido, o bash verifica se existe um comando encontrado na tabela de hash antes de tentar executá-lo. Se um comando hash não existir mais, uma pesquisa de caminho normal será executada.

Exemplo:

[blabla]$ PATH=$HOME/bin:$PATH
[blabla]$ hash -r
[blabla]$ cat bin/which
#!/bin/bash
echo "my which"
[blabla]$
[blabla]$ shopt -s checkhash
[blabla]$ which
my which
[blabla]$ mv bin/which bin/dis.which
[blabla]$ which which
/usr/bin/which
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.