如果您运行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
Run Code Online (Sandbox Code Playgroud)
根据手册页,哈希的目的是:
/usr/bin/hash 实用程序影响当前 shell 环境记住找到的实用程序位置的方式。根据指定的参数,它将实用程序位置添加到其记住的位置列表或清除列表的内容。当没有指定参数时,它报告列表的内容。该
-r选项会导致外壳忘记所有记住的位置。散列不报告作为 shell 内置程序提供的实用程序。
除了查看我输入了多少次命令之外,我看不到hash.
它甚至出现在 thegeekstuff.com 的前 15 个有用命令中
在哪些方面hash有用?
Bra*_*ley 106
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 ~]#
Run Code Online (Sandbox Code Playgroud)
如果您在$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 ~]#
Run Code Online (Sandbox Code Playgroud)
该cp命令导致新版本的ls可执行文件在我的较早出现,$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 ~]#
Run Code Online (Sandbox Code Playgroud)
如果您想从哈希表中删除某些内容并且不是 100% 可以注销然后成功重新登录,或者您想保留对 shell 所做的一些修改,那么您通常只想这样做。
要摆脱陈旧的映射,您还可以执行hash -r(或export PATH=$PATH) 以有效地清除 bash 的整个哈希表。
有很多这样的小情况。我不知道我是否会称它为“最有用”的命令之一,但它确实有一些用例。
ric*_*ici 41
这是简化的经典用法:
# 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.
Run Code Online (Sandbox Code Playgroud)
Gil*_*not 20
这是一个有用的用法hash:
hash php 2> /dev/null || hash -p /usr/local/foobar/php/bin/php php 2> /dev/null
Run Code Online (Sandbox Code Playgroud)
这意味着:如果 php 不在 PATH 中,则使用
/usr/local/foobar/php/bin/
Run Code Online (Sandbox Code Playgroud)
是的,Bash 参考手册说:
仅当在哈希表中未找到该命令时,才会对 $PATH 中的目录执行完整搜索。
但是您可以使用以下命令禁用散列set +h:
-h - 查找并记住(散列)命令,因为它们被查找以供执行。默认情况下启用此选项。
尝试:
set +h
hash # prints bash: hash: hashing disabled
echo $? # prints 1
Run Code Online (Sandbox Code Playgroud)
这同样适用于hash -r,hash NAME等
set -h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2 # prints nothing
set +h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2 # prints Please install ls
Run Code Online (Sandbox Code Playgroud)
你可以这样写:
old_options="$-"
set -h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
[[ "$old_options" =~ "h" ]] || set +h
Run Code Online (Sandbox Code Playgroud)
或(感谢@mikeserv)而无需分配任何新变量或进行任何测试:
set -h -- "-${-:--}" "$@"
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
set +h "$@"
Run Code Online (Sandbox Code Playgroud)