Disabilita la cache degli eseguibili di bash nel percorso


12

Si noti che questo non è un duplicato. Sto chiedendo di disabilitare la cache, non cancellarla. Se hai una cache da cancellare, ovviamente non è disabilitata.

Nelle rare occasioni in cui noto la cache di cose che Bash ha trovato nel percorso, non è perché è utile, è perché è dannatamente fastidioso. Un esempio:

~ 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

In un'altra shell ...

~ dc$ which which
/usr/bin/which

Sono sicuro che questa memorizzazione nella cache avesse senso ai vecchi tempi in cui i dischi erano lenti e la memoria era costosa e limitata e quindi non si poteva memorizzare molto nella cache: memorizzare un percorso nella cache è più economico che memorizzare nella cache tutti i blocchi del disco necessari per trovare un comando . Ma in questi giorni non offre alcun vantaggio evidente e causa più problemi di quanti ne risolva. È un malfunzionamento, in procinto di essere un bug.

E non riesco nemmeno a trovare un modo per disabilitarlo. Qualche puntatore?


1
I vantaggi sono evidenti anche nel caso comune di una macchina desktop, se non si dispone di così tanta RAM che /usr/binrimane interamente nella cache.
Gilles 'SO- smetti di essere malvagio' il

1
@drhyde, scusa. Ho contrassegnato questa domanda come duplicata. Utilizzare set +hper disabilitare l'hash.
Evgeny Vereshchagin,

In Nixos, ha disabilitato l'hash nella sua bash. Penso, per una buona ragione a causa del modo di lavorare di Nixos. Tuttavia, non sono sicuro che questo sia davvero obbligatorio per Nixos. Sto solo dicendo che un hash in bash può causare problemi in determinate situazioni.
dattiloscritto

Risposte:


12

Puoi semplicemente cancellare gli eseguibili con hash prima che il prompt venga disegnato:

PROMPT_COMMAND='hash -r'

Da 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
vedi la mia risposta suset +h
Evgeny Vereshchagin,

1
@EvgenyVereshchagin set +hnon è l'ideale, come chiamano molte utility (ad es. Installazioni di gemme di rubino) hash, producendo flussi di -bash: hash: hashing disabledavvisi.
David Moles,

Vedo anche gli stessi messaggi di avviso in un'attivazione virtualenv di Python. Ma penso che sia innocuo.
dattiloscritto

8

È possibile forzare bash a eseguire una nuova ricerca del percorso nel caso in cui non esista più un comando nella tabella hash.

shopt -s checkhash

Dalla manpage di bash:

checkhash

    Se impostato, bash verifica l'esistenza di un comando trovato nella tabella hash prima di provare a eseguirlo. Se non esiste più un comando con hash, viene eseguita una normale ricerca del percorso.

Esempio:

[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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.