Чому `type that` каже, що` hashe has`?


31

У випадку з оболонкою (наприклад, typeсама):

$ type type
type is a shell builtin

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

У випадку команд (зазвичай) (наприклад python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

У разі which(що є командою, розміщеною на /usr/bin/which)

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

Чому це type whichговорить which is hashed? У чому полягає значення whichхешування і що воно насправді означає?

Відповіді:


40

Ймовірно, у вас довгий набір PATH, і, щоб знайти виконуваний файл, оболонці потрібно шукати шлях. Щоб уникнути цього трудомісткого процесу щоразу, коли потрібно запустити програму, оболонка може зберігати список програм, які вона вже знайшла. Цей список називається "хеш". Коли оболонка каже, що whichхеш, це означає, що вона вже здійснила пошук PATH і знайшла whichта зберегла своє місцезнаходження в хеші.

man bash пояснює це так:

Bash використовує хеш-таблицю для запам'ятовування повних імен виконуваних файлів (див. Хеш під SHELL BUILTIN COMMANDS нижче). Повний пошук каталогів у PATH виконується лише в тому випадку, якщо команда не знайдена в хеш-таблиці.

Хоча хеш зазвичай прискорює операції з оболонками, є один випадок, коли це викликає проблеми. Якщо ви оновите свою систему і, як результат, деякі виконувані файли переміщуються на нове місце, оболонка може заплутатися. Рішення полягає в запуску, hash -rякий змушує оболонку забути всі хешовані місця та шукати PATH з нуля.

Чому в хеші відсутні деякі виконувані файли?

Виконаний файл не розміщується в хеші, поки ви не виконаєте принаймні один раз. Дотримуйтесь:

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

python хеширується лише після його виконання.

Як вивчити, що є в хеші Баша

Вміст хеша доступний у bashмасиві BASH_CMDS. З командою ви можете бачити, що в ній declare -p BASH_CMDS. Коли відкрита нова оболонка або допоміжна оболонка, хеш порожній. Команди додаються по черзі під час їх використання. З нещодавно відкритої оболонки спостерігайте:

$ 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, досить хороше пояснення. Але чому для whichі не для python?
приєднатися

@Jobin Дивіться оновлену відповідь.
John1024

2
Схоже, хеш зберігається лише до тих пір, поки ми не вийдемо з оболонки. Після перезавантаження терміналу він не говорить про те, що команда є хешованою.
Адітя

1
@Aditya Так. Я додав розділ про це у відповідь.
John1024

hash -lбуде простішим у використанні, ніжdeclare -p BASH_CMDS
phuclv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.