Perché `digitare che` dice che` che è hash`?


31

Nel caso di shell incorporate (ad es. Se typestesso):

$ type type
type is a shell builtin

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

In caso di comandi (normalmente) (ad es. python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

In caso di which(che è un comando situato in /usr/bin/which)

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

Perché lo type whichdice which is hashed? Qual è il significato whichdell'hash e cosa significa in realtà?

Risposte:


41

Probabilmente hai un lungo set di PATH e, per trovare un eseguibile, la shell deve cercare il percorso. Per evitare quel processo che richiede tempo ogni volta che si desidera eseguire un programma, la shell può mantenere un elenco di programmi che ha già trovato. Tale elenco è chiamato "hash". Quando la shell dice che whichè hash, significa che ha già fatto la ricerca PATH e trovato whiche salvato la sua posizione nell'hash.

man bash lo spiega come segue:

Bash usa una tabella hash per ricordare i nomi completi dei file eseguibili (vedi hash sotto COMANDI INCORPORATI SHELL di seguito). Una ricerca completa delle directory in PATH viene eseguita solo se il comando non viene trovato nella tabella hash.

Mentre l'hash accelera normalmente le operazioni della shell, c'è un caso in cui causa problemi. Se aggiorni il tuo sistema e, di conseguenza, alcuni eseguibili si spostano in una nuova posizione, la shell potrebbe confondersi. La soluzione consiste nell'eseguire hash -rche fa sì che la shell dimentichi tutte le posizioni con hash e cerchi il PERCORSO da zero.

Perché alcuni file eseguibili mancano dall'hash?

Un eseguibile non viene inserito nell'hash fino a dopo l'esecuzione almeno una volta. Osservare:

$ type python
python is /usr/bin/python
$ python --version
Python 2.7.3
$ type python
python is hashed (/usr/bin/python)

python viene hash solo dopo che è stato eseguito.

Come esaminare cosa c'è nell'hash di Bash

I contenuti dell'hash sono disponibili nella bashmatrice BASH_CMDS. Puoi vedere cosa c'è dentro con il comando declare -p BASH_CMDS. Quando viene aperta una nuova shell o subshell, l'hash è vuoto. I comandi vengono aggiunti uno ad uno man mano che vengono utilizzati. Da una shell appena aperta, osservare:

$ 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" )'

+1, spiegazione abbastanza buona. Ma perché per whiche non per python?
jobin

@Jobin Vedi la risposta aggiornata.
Giovanni 1024,

2
Sembra che l'hash persista solo fino al momento in cui non usciamo dalla shell. Una volta riavviato il terminale, non si dice che il comando sia stato cancellato.
Aditya,

1
@Aditya Sì. Ho aggiunto una sezione su questo alla risposta.
Giovanni 1024,

hash -lsarebbe più facile da usare rispetto adeclare -p BASH_CMDS
phuclv,
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.