Désactiver le cache bash des exécutables dans le chemin

12

Notez qu'il ne s'agit pas d' un doublon. Je demande de désactiver le cache, pas de le vider. Si vous avez un cache à vider, il n'est évidemment pas désactivé.

Les rares fois où je remarque le cache de bash des choses qu'il a trouvées sur le chemin, ce n'est pas parce qu'il est utile, c'est parce que c'est énervant. Un exemple:

~ 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

Dans une autre coquille ...

~ dc$ which which
/usr/bin/which

Je suis sûr que cette mise en cache était logique au bon vieux temps, lorsque les disques étaient lents et que la mémoire était chère et limitée et que vous ne pouviez donc pas beaucoup mettre en cache - la mise en cache d'un chemin est moins chère que la mise en cache de tous les blocs de disque nécessaires pour trouver une commande . Mais de nos jours, il n'offre aucun avantage notable et cause plus de problèmes qu'il n'en résout. C'est une erreur, qui frôle le fait d'être un bug.

Et je ne peux même pas trouver un moyen de le désactiver. Des pointeurs?

DrHyde
la source
1
Les avantages sont visibles même dans le cas commun d'une machine de bureau, si vous n'avez pas autant de RAM qui /usr/binreste entièrement dans le cache.
Gilles 'SO- arrête d'être méchant'
1
@drhyde, désolé. J'ai marqué cette question en double. Utilisez set +hpour désactiver le hachage.
Evgeny Vereshchagin
Dans Nixos, il a désactivé le hachage dans sa bash. Je pense, pour une bonne raison à cause de la façon de travailler de Nixos. Cependant, je ne sais pas si c'est vraiment obligatoire pour Nixos. Je dis seulement, qu'un hachage dans bash peut apporter des problèmes dans certaines situations.
typelogic

Réponses:

12

Vous pouvez simplement effacer les exécutables hachés avant que l'invite ne soit dessinée:

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.
Chris Down
la source
1
voir ma réponse à propos deset +h
Evgeny Vereshchagin
1
@EvgenyVereshchagin set +hn'est pas idéal, comme de nombreux utilitaires (par exemple les installations de rubis gemmes) appellent hash, produisant des flux d' -bash: hash: hashing disabledavertissements.
David Moles
Je vois également les mêmes messages d'avertissement dans une activation python virtualenv. Mais je pense que c'est inoffensif.
typelogic
8

Vous pouvez forcer bash à effectuer une nouvelle recherche de chemin au cas où une commande dans la table de hachage n'existe plus.

shopt -s checkhash

Depuis la page de manuel de bash:

checkhash

    S'il est défini, bash vérifie qu'une commande trouvée dans la table de hachage existe avant d'essayer de l'exécuter. Si une commande hachée n'existe plus, une recherche de chemin normale est effectuée.

Exemple:

[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
user70408
la source