答案1
当您输入命令时,如果没有哈希表,shell 将检查$PATH
变量中列出的每个目录,以查看是否在那里找到您的命令。
如果这些目录中的任何一个目录连接到速度较慢的设备,则这个过程可能会很慢。每次输入命令时,您都会遇到暂停的情况。
因此,当 shell 开始运行时,它会读取目录中的每个目录$PATH
并确定所有可执行程序,然后将此列表存储到内存中的哈希表中。然后,它无需再次检查它们,并且可以快速知道您输入的命令是否有效。
只要您不添加或删除程序,这种方法就很有效,因为一旦您这样做,哈希表就会过时。该rehash
命令的目的是要求 shell 再次读取程序列表。
以上内容适用于csh
和tcsh
。
使用bash
shell 时,它不会在启动时读取所有程序的名称。它确实会保留一个哈希表,但只会在您键入命令时将内容放入其中。例如:
bash-3.2$ ls
foo bar baz
bash-3.2$ cp
cp: missing file operand
Try `cp --help' for more information.
bash-3.2$ hash
hits command
1 /bin/cp
1 /bin/ls
cp
它记住了和命令的位置ls
。
答案2
虽然不同 shell 之间存在差异,但总体来说还是比较简单的。为了避免不必要的 IO,shell 维护了一个将可执行文件名称映射到其完整路径的表。
zsh 有两个与此相关的选项,均默认启用:
哈希_CMDS
<D>
第一次执行每个命令时,记下其位置。后续调用同一命令时将使用保存的位置,从而避免路径搜索。如果未设置此选项,则根本不进行路径哈希处理。但是,当设置 CORRECT 时,名称未出现在函数或别名哈希表中的命令将被哈希处理,以避免将其报告为拼写错误。
哈希目录
<D>
每当命令名称被哈希化时,都会哈希化包含该命令名称的目录以及路径中较早出现的所有目录。如果未设置 HASH_CMDS 或 CORRECT,则无效。
使用这些选项,将目录(和新命令)附加到 PATH 应该可以按预期工作。但是,如果您将一个目录附加到应该优先于某个命令(例如/usr/local/bin/ls
)的路径,则可能必须重新散列或重新启动 shell。