在路径中禁用bash的可执行文件缓存


12

请注意,这不是重复项。我要问的是禁用缓存,而不是清除它。如果您有要清除的缓存,则显然不会禁用它。

在极少数情况下,我会注意到bash在路径中发现的东西缓存,这并不是因为它有用,而是因为它令人讨厌。一个例子:

~ dc$ export PATH=$HOME/bin:$PATH
~ dc$ cat bin/which
#!/bin/bash
echo "my which"
~ dc$ which
my which
~ dc$ rm bin/which
~ dc$ which which
-bash: /Users/dc/bin/which: No such file or directory

在另一个外壳...

~ dc$ which which
/usr/bin/which

我敢肯定,这种高速缓存在磁盘速度慢,内存昂贵且有限的美好旧时光中很有意义,因此您不能缓存太多-缓存路径比缓存查找命令所需的所有磁盘块便宜。但是这些天来,它并没有带来明显的好处,并且带来了许多无法解决的问题。这是一个错误的功能,很快就会成为错误。

而且我什至找不到禁用它的方法。有指针吗?


1
即使您没有太多的RAM /usr/bin完全保留在缓存中,即使在台式机的常见情况下,好处也很明显。
吉尔斯(Gillles)“所以-别再邪恶了”

1
@drhyde,对不起。我将此问题标记为重复。使用set +h禁用哈希。
Evgeny Vereshchagin

在Nixos中,它在bash中禁用了哈希。我认为,由于Nixos的工作方式,这是有充分理由的。但是,我不确定这是否真的对Nixos强制。我只是说,bash中的哈希在某些情况下会带来问题。
typelogic

Answers:


12

您可以在绘制提示之前清除散列的可执行文件:

PROMPT_COMMAND='hash -r'

来自help hash

hash: hash [-lr] [-p pathname] [-dt] [name ...]
Remember or display program locations.

Determine and remember the full pathname of each command NAME.  If
no arguments are given, information about remembered commands is displayed.

Options:
  -d                forget the remembered location of each NAME
  -l                display in a format that may be reused as input
  -p pathname       use PATHNAME is the full pathname of NAME
  -r                forget all remembered locations
  -t                print the remembered location of each NAME, preceding
            each location with the corresponding NAME if multiple
            NAMEs are given
Arguments:
  NAME              Each NAME is searched for in $PATH and added to the list
            of remembered commands.

Exit Status:
Returns success unless NAME is not found or an invalid option is given.

1
看到我的回答set +h
叶夫根韦列夏金

1
@EvgenyVereshchagin set +h并不理想,因为许多实用程序(例如ruby gem安装)都调用hash,产生-bash: hash: hashing disabled警告流。
David Moles

我还在python virtualenv激活中看到了相同的警告消息。但我认为,这是无害的。
typelogic

8

如果哈希表中的命令不再存在,则可以强制bash执行新的路径查找。

shopt -s checkhash

从bash的联机帮助页中:

检查哈希

    如果设置,bash会在尝试执行之前检查在哈希表中找到的命令是否存在。如果哈希命令不再存在,则执行常规路径搜索。

例:

[blabla]$ PATH=$HOME/bin:$PATH
[blabla]$ hash -r
[blabla]$ cat bin/which
#!/bin/bash
echo "my which"
[blabla]$
[blabla]$ shopt -s checkhash
[blabla]$ which
my which
[blabla]$ mv bin/which bin/dis.which
[blabla]$ which which
/usr/bin/which
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.