Скорее всего, у вас длинный набор 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" )'
which
а не дляpython
?