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

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

当我执行一个程序而不指定可执行文件的完整路径时,Bash 必须搜索目录以$PATH查找二进制文件,似乎 Bash 会记住某种缓存中的路径。例如,我从源代码安装了 Subversion 版本,然后在 Bash 提示符下/usr/local键入。 svnsync helpBash 找到“svnsync”的二进制文件/usr/local/bin/svnsync并执行它。然后当我删除 Subversion 的安装/usr/local并重新运行时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 hashman bash

答案2

还有这里没有提到的解决方案。

  1. 您可以使用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
    
  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 NAME您可以使用或将 NAME 与 PATH 绑定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
    
  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
    

答案3

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

hash -d svnsync

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

答案4

作为用户约翰泰克斯在评论中指出回答按用户东武,Bash 中最简单的实际操作就是重新哈希您的程序:

hash svnsync

就这样。

相关内容