$PATH
中搜索目录以找到二进制文件时,Bash似乎在某种缓存中记住了该路径。例如,我安装了一个从源到/usr/local
的Subversion版本,然后在Bash提示符下键入svnsync help
。 Bash找到“ svnsync”的二进制/usr/local/bin/svnsync
并执行了它。然后,当我在/usr/local
中删除Subversion的安装并重新运行svnsync help
时,Bash会响应:bash: /usr/local/bin/svnsync: No such file or directory
但是,当我启动一个新的Bash实例时,它会发现并执行
/usr/bin/svnsync
。如何清除可执行文件路径的缓存?
#1 楼
bash
确实缓存了命令的完整路径。您可以验证使用type
命令对要执行的命令进行哈希处理:$ type svnsync
svnsync is hashed (/usr/local/bin/svnsync)
要清除整个缓存,请执行以下操作:
$ hash -r
或仅一个条目:
$ hash -d svnsync
有关其他信息,请参阅
help hash
和man bash
。评论
@Daniel值得补充的是,在bash中,您可以使用命令“ type command”来查找命令的类型-如果您的命令是散列的,“ type”将告诉您。告诉某些内容是内置的Shell还是别名也很有用。
–午餐
2011年5月11日在20:59
作为一个仅供参考,如果要运行csh来更改缓存的PATH,请重新哈希该命令。
–kurtm
13-10-12在0:21
上面的rehash命令也适用于zsh。
–尼尔·特拉夫(Neil Traft)
13年10月10日在21:35
在一个命令中,可以通过哈希svnsync调用选择性重新哈希。
–艾奥尼斯·菲利皮迪斯(Ioannis Filippidis)
14年8月9日,0:44
我发现我正在运行破折号而不是bash-因为破折号哈希-d不起作用;哈希svnsync都适用。
– Iiridayn
16 Jul 19'0:10
#2 楼
要只清除一个条目,您需要一个不同的标志:hash -d svnsync
-r
标志没有参数,并且将始终删除整个缓存。#3 楼
有此处未提及的解决方案。您可以使用
set +h
或set +o hashall
禁用散列help set
说:-h-在查找要执行的命令时记住其位置。默认情况下启用此功能。
hashall-与-h
set -h # enable hashing
shopt -u checkhash # disable command existence check
hash -p /some/nonexisting/dir/date date # bind date with /some/nonexisting/dir/date
date # bash: /some/nonexisting/dir/date: No such file or directory
set +h
date # normal date output
在尝试使用
shopt -s checkhash
执行哈希表中找到的命令之前,该命令已存在help shopt
说:checkhash-如果已设置,则bash会检查在哈希表在尝试执行之前存在。如果不再存在哈希命令,则将执行常规路径搜索。
set -h # enable hashing
shopt -u checkhash # disable command existence check
hash -p /some/nonexisting/dir/date date # bind date with /some/nonexisting/dir/date
hash -t date # prints /some/nonexisting/dir/date
date # bash: /some/nonexisting/dir/date: No such file or directory
shopt -s checkhash # enable command existence check
date # normal date output
hash -t date # prints /bin/date
您可以将NAME与PATH绑定在一起,并带有
hash -p PATH NAME
或BASH_CMDS[NAME]=PATH
:shopt -u checkhash # disable command existence check
hash -p /some/nonexisting/dir/date date
date # bash: /some/nonexisting/dir/date: No such file or directory
BASH_CMDS[date]=/bin/date
date # normal date output
魔术:
PATH="$PATH"
执行hash -r
从
variables.c
开始:/* What to do just after the PATH variable has changed. */
void
sv_path (name)
char *name;
{
/* hash -r */
phash_flush ();
}
尝试:
set -h
hash -r
date
hash # prints 1 /bin/date
PATH="$PATH"
hash # prints hash: hash table empty
评论
我从来不明白为什么当PATH = $ PATH正常工作时会提供所有额外的机制。如果PATH更改,则PATH查找缓存应无效。说得通。
– jrw32982
16年7月27日在19:48
当PATH更改时,不能通过使高速缓存无效来处理的用例是可执行文件的位置更改时。当您使用外壳程序添加或删除程序时,仅使它缓存找到程序的最后位置时,这种情况很常见。
–亚当
17年12月7日在21:31
弄乱命令哈希表是一种真正使尝试调试bash脚本的人感到困惑的绝妙方法。
– Erik Aronesty
18年1月29日在18:12
#4 楼
正如用户johntex在对Tobu用户的回答的评论中指出的那样,Bash中最简单的实际操作是仅对您的程序进行哈希处理:hash svnsync
就这么简单。
评论
有史以来最愚蠢的功能bash缓存车祸?
@Romeno该功能非常好(重新运行命令可以节省时间),这是愚蠢的实现。 Bash应该自动删除不再存在可执行文件的哈希。