hash命令的目的是什么?

hash命令的目的是什么?

如果运行,hash它会显示自上次重置哈希以来运行的所有命令的路径 ( hash -r)

[root@c04c ~]# hash
hash: hash table empty

[root@c04c ~]# whoami
root

[root@c04c ~]# hash
hits    command
   1    /usr/bin/whoami

[root@c04c ~]# whoami
root

[root@c04c ~]# hash
hits    command
   2    /usr/bin/whoami

根据手册页,哈希的目的是:

/usr/bin/hash 实用程序会影响当前 shell 环境记住所找到的实用程序位置的方式。根据指定的参数,它将实用程序位置添加到其记住的位置列表中,或者清除列表的内容。当未指定参数时,它将报告列表的内容。该-r选项会导致 shell 忘记所有记住的位置。

作为内置程序提供给 shell 的实用程序不会通过哈希报告。

除了查看我输入命令的次数之外,我看不到 的实用性hash

它甚至出现在 thegeekstuff.com 的15 个最有用的命令

在哪些方面hash有用?

答案1

hash是 bash 的内置命令。哈希表的一项功能是将结果缓存在内存中,从而bash 避免$PATH每次键入命令时都必须进行搜索。对于明显使结果无效的事件(例如修改$PATH),该表将被清除

hash命令就是您与该系统交互的方式(无论您认为需要什么原因)。

一些用例:

  • 就像您看到的那样,如果您不带参数键入命令,它会打印出您点击哪些命令的次数。这可能会告诉您最常使用哪些命令。

  • 您还可以使用它来记住非标准位置的可执行文件。

例子:

[root@policyServer ~]# hash -p /lol-wut/whoami whoami
[root@policyServer ~]# whoami
Not what you’re thinking
[root@policyServer ~]# which whoami
/usr/bin/whoami
[root@policyServer ~]# /usr/bin/whoami
root
[root@policyServer ~]#

如果您在要运行的目录之外的目录中只有一个可执行文件,$PATH只需键入名称而不是包含该目录中的所有内容(如果将其添加到$PATH),这可能会很有用。

别名通常也可以做到这一点,但由于您正在修改当前 shell 的行为,因此它不会映射到您启动的程序中。单独的可执行文件的符号链接可能是这里的更好选择。hash是一种方法。

  • 您可以使用它来忘记文件路径。如果一个新的可执行文件在较早的目录中弹出PATH或被转移mv到其他地方,并且您想要强制 bash 再次查找它,而不是它记得的最后一个找到它的位置,那么这非常有用。

例子:

[root@policyServer ~]# hash
hits    command
   1    /bin/ls
[root@policyServer ~]# cp /bin/ls /lol-wut
[root@policyServer ~]# hash
hits    command
   1    /bin/cp
   1    /bin/ls
[root@policyServer ~]# hash -d ls
[root@policyServer ~]# ls
default.ldif  newDIT.ldif  notes.txt  users.ldif
[root@policyServer ~]# hash
hits    command
   1    /bin/cp
   1    /lol-wut/ls
[root@policyServer ~]#

cp命令导致可执行文件的新版本ls较早地出现在 my 中,$PATH但没有触发哈希表的清除。我曾经有选择地从哈希表中hash -d清除条目。ls然后,Bash 被迫再次查找$PATH,当它查找时,它在较新的位置找到了它(在 $PATH 中比之前运行的位置更早)。

不过,您可以有选择地调用此“从中查找可执行文件的新位置$PATH”行为:

[root@policyServer ~]# hash
hits    command
   1    /bin/ls
[root@policyServer ~]# hash ls
[root@policyServer ~]# hash
hits    command
   0    /lol-wut/ls
[root@policyServer ~]#

如果您想要从哈希表中获取某些内容,并且不是 100% 可以注销然后成功返回,或者您想保留对 shell 所做的一些修改,那么您大多只想执行此操作。

要摆脱陈旧的映射,您还可以执行hash -r(或export PATH=$PATH) 操作,这会有效地清除 bash 的整个哈希表。

类似这样的小情况还有很多。我不知道我是否会称其为“最有用”的命令之一,但它确实有一些用例。

答案2

这是简化的经典用法:

# My PATH contains /home/rici/bin as well as the Usual Suspects:
# (the real one has lots more)
$ echo $PATH
/home/rici/bin:/usr/local/bin:/usr/bin:/bin

# I've installed a program called hello in /usr/local/bin
$ $ cat /usr/local/bin/hello
#!/bin/bash

echo Hello, world. I live at $0

# The program works.
$ hello
Hello, world. I live at /usr/local/bin/hello

# Now I want to create a better hello, just for me. I put it in
# my own bin directory, and according to my PATH, it should come first.
$ cp /usr/local/bin/hello ~/bin/hello

# So now I will try running it
$ hello
Hello, world. I live at /usr/local/bin/hello

# WTF? Oh, forgot to run hash.
# Tell bash to update where to look for hello
$ hash hello
$ hello
Hello, world. I live at /home/rici/bin/hello

# Ah, all is well.

答案3

这是一个有用的用法hash

hash php 2> /dev/null || hash -p /usr/local/foobar/php/bin/php php 2> /dev/null

这意味着:如果 php 不在 PATH 中,则使用

/usr/local/foobar/php/bin/

答案4

轻松检测命令是否可用:

CMD=gzip
if hash bzip2; then
    CMD=$_
fi

相关内容