Prawdopodobnie masz długi zestaw PATH i aby znaleźć plik wykonywalny, powłoka musi przeszukać ścieżkę. Aby uniknąć tego czasochłonnego procesu za każdym razem, gdy chcesz uruchomić program, powłoka może przechowywać listę programów, które już znalazła. Ta lista nazywa się „skrótem”. Kiedy powłoka mówi, że which
jest zaszyfrowana, oznacza to, że już przeprowadziła wyszukiwanie ŚCIEŻKI, znalazła which
i zapisała swoją lokalizację w haszowaniu.
man bash
wyjaśnia to w następujący sposób:
Bash używa tabeli skrótów do zapamiętywania pełnych ścieżek plików wykonywalnych (patrz skrót w POLECENIA WBUDOWANE POWŁOKI poniżej). Pełne wyszukiwanie katalogów w zmiennej PATH jest wykonywane tylko wtedy, gdy polecenia nie znaleziono w tabeli skrótów.
Podczas gdy skrót zwykle przyspiesza operacje powłoki, jest jeden przypadek, w którym powoduje problemy. Jeśli zaktualizujesz system, w wyniku czego niektóre pliki wykonywalne zostaną przeniesione do nowej lokalizacji, powłoka może się pomylić. Rozwiązaniem jest uruchomienie, hash -r
które powoduje, że powłoka zapomina o wszystkich zakodowanych lokalizacjach i przeszukuje ŚCIEŻKĘ od zera.
Dlaczego w haszu brakuje niektórych plików wykonywalnych?
Plik wykonywalny nie jest umieszczany w haszu, dopóki nie zostanie wykonany przynajmniej raz. Przestrzegać:
$ type python
python is /usr/bin/python
$ python --version
Python 2.7.3
$ type python
python is hashed (/usr/bin/python)
python
jest mieszany dopiero po jego wykonaniu.
Jak sprawdzić, co jest w haszu bash
Zawartość skrótu jest dostępna w bash
tablicy BASH_CMDS
. Za pomocą polecenia możesz zobaczyć, co jest w środku declare -p BASH_CMDS
. Po otwarciu nowej powłoki lub podpowłoki skrót jest pusty. Polecenia są dodawane jeden po drugim, gdy są używane. Z nowo otwartej powłoki obserwuj:
$ 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" )'
which
a nie zapython
?hash -l
byłoby łatwiejsze w użyciu niżdeclare -p BASH_CMDS