Почему `type that 'говорит то, что' hashed`?


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хеширования и что это на самом деле означает?

Ответы:


41

Скорее всего, у вас длинный набор 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массиве 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

@Jobin Смотрите обновленный ответ.
John1024

2
Похоже, хеш сохраняется только до тех пор, пока мы не выйдем из оболочки. Как только мы перезапускаем терминал, он не говорит, что команда хэшируется.
Адитья

1
@ Aditya Да. Я добавил раздел об этом в ответ.
John1024

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