为什么“type which”会说“which is hashed”?

为什么“type which”会说“which is hashed”?

对于 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

答案1

您可能设置了很长的 PATH,为了找到可执行文件,shell 需要搜索该路径。为了避免每次要运行程序时都耗费时间,shell 可能会保留一个已找到的程序列表。该列表称为“哈希”。当 shell 说已which哈希时,这意味着它已经完成 PATH 搜索,并which在哈希中找到并保存了其位置。

man bash解释如下:

Bash 使用哈希表来记住可执行文件的完整路径名(请参阅下文 SHELL BUILTIN COMMANDS 下的哈希)。仅当哈希表中未找到命令时,才会对 PATH 中的目录进行完整搜索。

虽然哈希通常会加快 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" )'

相关内容