web-dev-qa-db-ja.com

実行可能ファイルへのパスのBashのキャッシュをクリアするにはどうすればよいですか?

実行可能ファイルへのフルパスを指定せずにプログラムを実行し、Bashが$PATH内のディレクトリを検索してバイナリを見つける必要がある場合、Bashはある種のキャッシュでパスを記憶しているようです。たとえば、Subversionのビルドをソースから/usr/localにインストールし、Bashプロンプトでsvnsync helpと入力しました。 Bashは「svnsync」のバイナリ/usr/local/bin/svnsyncを見つけて実行しました。次に、/usr/localのSubversionのインストールを削除してsvnsync helpを再実行すると、Bashが応答します。

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

または、ただ1つのエントリ:

$ hash -d svnsync

詳細については、help hashおよびman bashをご覧ください。

349
Tobu

1つのエントリだけをクリアするには、別のフラグが必要です。

hash -d svnsync

-rフラグはパラメーターをとらず、常にキャッシュ全体を削除します。
(少なくともDebian Lennyのbash 3.2.39で)

27

ここで言及されていない解決策があります。

  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をhash -p PATH NAMEまたはBASH_CMDS[NAME]=PATHで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

ユーザー johntex がコメント answer by user Tob にコメントしているので、Bashでの最も単純な実際的なアクションは、プログラムだけを再ハッシュすることです。

hash svnsync

それで全部です。

5
Acumenus