为什么`type which` 说`which is hashed`?

Adi*_*tya 50 command-line

如果是 shell-builtins(例如type本身):

$ type type
type is a shell builtin

$ which type
<Doesn't return anything since it's a shell builtin, silently exits>
Run Code Online (Sandbox Code Playgroud)

在命令的情况下(通常)(例如python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python
Run Code Online (Sandbox Code Playgroud)

如果which(这是一个位于 的命令/usr/bin/which)

$ type which
which is hashed (/usr/bin/which)
$ which which
/usr/bin/which
Run Code Online (Sandbox Code Playgroud)

为什么type which这么说which is hashedwhich被散列的意义是什么,它实际上意味着什么?

Joh*_*024 62

您可能设置了很长的 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)
Run Code Online (Sandbox Code Playgroud)

python 仅在执行后才进行散列。

如何检查 bash 的哈希值

散列的内容在bash数组中可用BASH_CMDS。您可以使用命令查看其中的内容declare -p BASH_CMDS。当打开一个新的 shell 或 subshel​​l 时,散列是空的。命令在使用时一一添加。从新打开的外壳中,观察:

$ 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" )'
Run Code Online (Sandbox Code Playgroud)

  • `hash -l` 比 `declare -p BASH_CMDS` 更容易使用 (4认同)
  • 看起来哈希值只存在到我们不退出 shell 的时候。一旦我们重新启动终端,它就不会说命令是散列的。 (3认同)