Como faço para limpar o cache de caminhos do Bash para executáveis?

234

Quando executo um programa sem especificar o caminho completo para o executável, e o Bash deve procurar os diretórios em $PATH para encontrar o binário, parece que o Bash se lembra do caminho em algum tipo de cache. Por exemplo, eu instalei uma compilação do Subversion da fonte para /usr/local , depois digitei svnsync help no prompt do Bash. Bash localizou o binário /usr/local/bin/svnsync para o "svnsync" e o executou. Então, quando apaguei a instalação do Subversion em /usr/local e executei novamente o svnsync help , o Bash responde:

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

Mas, quando eu inicio uma nova instância do Bash, ele encontra e executa /usr/bin/svnsync .

Como faço para limpar o cache de caminhos para executáveis?

    
por Daniel Trebbien 10.01.2011 / 02:50

4 respostas

292

bash armazena em cache o caminho completo para um comando. Você pode verificar se o comando que você está tentando executar está com o comando type :

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

Para limpar todo o cache:

$ hash -r

Ou apenas uma entrada:

$ hash -d svnsync

Para informações adicionais, consulte help hash e man bash .

    
por 10.01.2011 / 02:59
24

Para limpar apenas uma entrada, você precisa de um sinalizador diferente:

hash -d svnsync

O sinalizador -r não aceita um parâmetro e sempre exclui o cache inteiro.
(Pelo menos no bash 3.2.39 no Debian Lenny)

    
por 16.03.2011 / 16:30
18

Existem soluções não mencionadas aqui.

  1. Você pode desativar o hash com set +h ou set +o hashall

    help set diz:

    -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. Você pode verificar se um comando encontrado na tabela de hash existe antes de tentar executá-lo com shopt -s checkhash

    help shopt diz:

    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. Você pode vincular NAME a PATH com hash -p PATH NAME ou 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. Magia: PATH="$PATH" executa hash -r

    Em variables.c :

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

    Tente:

    set -h
    hash -r
    date
    hash # prints 1 /bin/date
    PATH="$PATH"
    hash # prints hash: hash table empty
    
por 27.07.2015 / 20:26
3

Como o usuário johntex observou em um comentário ao answer pelo usuário Tobu , a ação prática mais simples no Bash é para refazer apenas o seu programa:

hash svnsync

Isso é tudo.

    
por 26.09.2014 / 21:25