Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question

4 Answers 4

up vote 109 down vote accepted

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.

share|improve this answer
1  
Thank you very much! –  Daniel Trebbien Jan 10 '11 at 15:40
12  
@Daniel It's worth adding that, in bash, you can use the command "type command" to find out what type of command it is - if your command is hashed, "type" will tell you. It's also useful to tell whether something's a shell builtin or an alias. –  lunchmeat317 May 11 '11 at 20:59
    
+1. I had not idea, but had a similar problem with the id command. –  deuberger May 17 '11 at 16:11
4  
As an FYI, to change the cached PATH if running csh, the command is rehash. –  kurtm Oct 12 '13 at 0:21
1  
In one command selective rehashing can be invoked by hash svnsync. –  Ioannis Filippidis Aug 9 '14 at 0:44

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
    
share|improve this answer

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.

share|improve this answer

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)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.