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
可执行文件较早地出现在我的$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 q4312078q
# 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.
评论
如此处所述,可以使用单个命令哈希问候调用哈希表的选择性更新。
–艾奥尼斯·菲利皮迪斯(Ioannis Filippidis)
2014年8月9日下午0:42
@johntex:好的,更改了。
–rici
2014年8月9日在6:10
在知道哈希表存在之前,想象一下潜在的奇怪错误!是否存在自动刷新哈希表的情况列表?
– Benjimin
19年6月28日在1:00
@benji:永远不会自动刷新(整体上)。如果在posix模式下运行bash或setopt -s checkhash并且命令的哈希可执行文件不再存在,则该命令的哈希条目将被更新。但是请注意,每个bash会话都有自己的哈希表,因此关闭会话并开始一个新的会话实际上会清空该哈希。 (哈希-r是更简单的方法。)
–rici
19年6月28日在1:47
更新$ PATH或启动新的bash终端,似乎都可以清除表。
– Benjimin
19年6月28日在6:52
#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 楼
是的,《 Bash参考手册》说:仅当在哈希表中找不到命令时,才对$ PATH中的目录进行完全搜索。
,但是您可以使用
set +h
禁用散列:-h-查找并记住(散列)命令以查找其执行。默认情况下启用此选项。
尝试:
set +h
hash # prints bash: hash: hashing disabled
echo $? # prints 1
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
您可以编写如下内容:
old_options="$-"
set -h
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
[[ "$old_options" =~ "h" ]] || set +h
或(感谢@mikeserv)而不必分配任何新变量或进行任何测试:
set -h -- "-${-:--}" "$@"
hash ls >/dev/null 2>&1 || echo "Please install ls" >&2
set +h "$@"
评论
对于您的old_options事情-我通常会执行以下操作:set -h-“-$ {-:-}”“ $ @”;哈希...;设置+ h“ $ @”,这样就可以自动将它们全部放置到位,而无需分配任何新变量或进行任何测试或其他操作。
–mikeserv
15年7月29日在11:28
#5 楼
轻松检测命令是否可用:CMD=gzip
if hash bzip2; then
CMD=$_
fi
评论
我想知道“哈希”这个名字的来源。那例如“缓存”呢? :)。
–迈克尔
13年8月8日在20:11
@Michael因为hash命令在内部使用哈希表来存储映射。 zh.wikipedia.org/wiki/Hash_table
– jlliagre
13年8月8日在20:39
应该注意的是,哈希不是bash特定的,命令起源于SVR2的Bourne shell(尽管命令的哈希路径之前是csh的功能),并且在所有类似Bourne和POSIX的shell中都可以找到。
–StéphaneChazelas
13年8月8日在21:34
代替使用export PATH = $ PATH来清除表,哈希-r应该足够。
– ravron
16年1月4日在18:52
另一个用例是在$ PATH的较早部分中安装程序的第二个副本。您需要对-r进行哈希处理,否则将获得旧版本,因为$ PATH不变,因此Bash并未意识到它可以从较早(优先级更高)的目录中加载相同的程序。有关详细信息,请参见conda.pydata.org/docs/…。
– John Zwinck
17年1月19日在4:26