How do I clear Bash's cache of paths to executables?

When I execute a program without specifying the full path to the executable, and Bash must search the directories in $PATH to find the binary, it seems that Bash remembers the path in some sort of cache. For example, I installed a build of Subversion from source to /usr/local, then typed svnsync help at the Bash prompt. Bash located the binary /usr/local/bin/svnsync for “svnsync” and executed it. Then when I deleted the installation of Subversion in /usr/local and re-ran svnsync help, Bash responds:

bash: /usr/local/bin/svnsync: No such file or directory

But, when I start a new instance of Bash, it finds and executes /usr/bin/svnsync.

How do I clear the cache of paths to executables?

Asked By: Daniel Trebbien

||

bash does cache the full path to a command. You can verify that the command you are trying to execute is hashed with the type command:

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

To clear the entire cache:

$ hash -r

Or just one entry:

$ hash -d svnsync

For additional information, consult help hash and man bash.

Answered By: Tobu

To clear just one entry you need a different flag:

hash -d svnsync

The -r flag doesn’t take a parameter and will always delete the entire cache.
(At least in bash 3.2.39 on Debian Lenny)

Answered By: Aryeh Leib Taurog

As user johntex has noted in a comment to the answer by user Tobu, the simplest practical action in Bash is to rehash just your program:

hash svnsync

That’s all.

Answered By: Asclepius

There are solutions not mentioned here.

  1. You can disable hashing with set +h or set +o hashall

    help set says:

    -h – Remember the location of commands as they are looked up for execution. This is enabled by default.

    hashall – Same as -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. You can check that a command found in the hash table exists before trying to execute it with shopt -s checkhash

    help shopt says:

    checkhash – If set, bash checks that a command found in the hash table exists before trying to execute it. If a hashed command no longer exists, a normal path search is performed.

    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. You can bind NAME with PATH with hash -p PATH NAME or 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. Magic: PATH="$PATH" performs hash -r

    From variables.c:

    /* What to do just after the PATH variable has changed. */
    void
    sv_path (name)
        char *name;
    {
        /* hash -r */
        phash_flush ();
    }
    

    Try:

    set -h
    hash -r
    date
    hash # prints 1 /bin/date
    PATH="$PATH"
    hash # prints hash: hash table empty
    
Answered By: Evgeny Vereshchagin
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.