it-swarm-ru.tech

Как очистить кэш путей Bash к исполняемым файлам?

Когда я запускаю программу без указания полного пути к исполняемому файлу, Bash должен искать каталоги в $PATH, чтобы найти двоичный файл, похоже, что Bash запоминает путь в каком-то кеше. Например, я установил сборку Subversion из исходного кода в /usr/local, затем набрал svnsync help в Bash Prompt. Баш нашел двоичный файл /usr/local/bin/svnsync для "svnsync" и выполнил его. Затем, когда я удалил установку Subversion в /usr/local и ​​перезапущен svnsync help, Баш отвечает:

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 hash а также man bash.

349
Tobu

Чтобы очистить только одну запись, вам нужен другой флаг:

hash -d svnsync

-r флаг не принимает параметр и всегда удаляет весь кеш.
(По крайней мере, в bash 3.2.39 на Debian Lenny)

27
Aryeh Leib Taurog

Есть решения, не упомянутые здесь.

  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. Вы можете связать NAME с PATH с помощью hash -p PATH NAME или 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
    
24
Evgeny Vereshchagin

Как отметил пользователь johntex в комментарии к answer пользователем Tob , самое простое практическое действие в Bash - перефразировать только вашу программу:

hash svnsync

Это все.

5
Acumenus