问题描述
对于shell-builtins(例如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
被散列的意义是什么?它的实际含义是什么?
最佳方案
您可能设置了很长的PATH,并且要找到可执行文件,shell需要搜索路径。为了避免每次您要运行程序时耗时的过程,shell可能会保留已找到的程序列表。该列表称为”hash.”。如果 shell 程序说which
已被散列,则意味着它已经进行了PATH搜索并找到了which
,并将其位置保存在散列中。
man bash
解释如下:
Bash uses a hash table to remember the full pathnames of executable files (see hash under SHELL BUILTIN COMMANDS below). A full search of the directories in PATH is performed only if the command is not found in the hash table.
虽然散列通常可以加快 shell 程序的运行速度,但在某些情况下会引起问题。如果更新系统,结果某些可执行文件移至新位置,则 shell 可能会感到困惑。解决方案是运行hash -r
,这会使 shell 程序忘记所有散列的位置并从头开始搜索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
查看其中的内容。当打开新的 shell 程序或子 shell 程序时,哈希为空。使用命令时,命令会一一添加。在新打开的 shell 中,观察:
$ 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" )'