it-swarm.cn

如何清除Bash可执行文件路径的缓存?

当我执行程序时未指定可执行文件的完整路径,并且Bash必须在$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

如何清除可执行文件路径的缓存?

276
Daniel Trebbien

bash确实缓存了命令的完整路径。您可以使用type命令验证要执行的命令是否为哈希值:

$ type svnsync
svnsync is hashed (/usr/local/bin/svnsync)

要清除整个缓存:

$ hash -r

或者只是一个条目:

$ hash -d svnsync

有关其他信息,请咨询help hashman bash

349
Tobu

要只清除一个条目,您需要一个不同的标志:

hash -d svnsync

-r标志不带参数,它将始终删除整个缓存。
(至少在Debian Lenny的bash 3.2.39中)

27
Aryeh Leib Taurog

这里没有提到解决方案。

  1. 您可以使用set +hset +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
    
  2. 在尝试使用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
    
  3. 您可以使用hash -p PATH NAMEBASH_CMDS[NAME]=PATH将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
    
  4. 魔术: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
    
24
Evgeny Vereshchagin

正如用户 johntex 在对用户 answer 的评论中提到的 Tob 一样,Bash中最简单的实际操作是重新哈希程序:

hash svnsync

就这样。

5
Acumenus