Bagaimana cara menghapus cache path Bash ke executable?


256

Ketika saya menjalankan program tanpa menentukan path lengkap ke executable, dan Bash harus mencari direktori $PATHuntuk menemukan biner, tampaknya Bash mengingat path dalam semacam cache. Misalnya, saya memasang build Subversion dari sumber ke /usr/local, lalu mengetik svnsync helpdi Bash prompt. Bash menemukan biner /usr/local/bin/svnsyncuntuk "svnsync" dan menjalankannya. Lalu ketika saya menghapus instalasi Subversion di /usr/localdan berlari kembali svnsync help, Bash menjawab:

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

Tetapi, ketika saya memulai instance baru Bash, ia menemukan dan mengeksekusi /usr/bin/svnsync.

Bagaimana cara menghapus cache path ke executable?


7
fitur paling konyol yang pernah
Romeno

Jawaban:


322

bashmelakukan cache path lengkap ke sebuah perintah. Anda dapat memverifikasi bahwa perintah yang Anda coba jalankan terpotong dengan typeperintah:

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

Untuk menghapus seluruh cache:

$ hash -r

Atau hanya satu entri:

$ hash -d svnsync

Untuk informasi tambahan, konsultasikan help hashdan man bash.


15
@Daniel Perlu menambahkan bahwa, dalam bash, Anda dapat menggunakan perintah "ketik perintah " untuk mencari tahu jenis perintah itu - jika perintah Anda di-hash, "ketik" akan memberi tahu Anda. Ini juga berguna untuk mengetahui apakah ada sesuatu yang merupakan builtin shell atau alias.
lunchmeat317

4
Sebagai FYI, untuk mengubah PATH yang di-cache jika dijalankan csh, perintahnya adalah rehash.
kurtm

rehashPerintah di atas juga berfungsi untuk zsh.
Neil Traft

Untuk jawaban yang lebih lengkap lihat unix.stackexchange.com/questions/86012/...
Ioannis Filippidis

4
Dalam satu perintah, pengulangan selektif dapat dilakukan oleh hash svnsync.
Ioannis Filippidis

25

Untuk menghapus hanya satu entri, Anda memerlukan bendera yang berbeda:

hash -d svnsync

The -rBendera tidak mengambil parameter dan akan selalu menghapus seluruh cache.
(Setidaknya dalam bash 3.2.39 tentang Debian Lenny)


20

Ada solusi yang tidak disebutkan di sini.

  1. Anda dapat menonaktifkan hashing dengan set +hatauset +o hashall

    help set mengatakan:

    -h - Ingat lokasi perintah ketika mereka dicari untuk dieksekusi. Ini diaktifkan secara default.

    hashall - Sama seperti -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. Anda dapat memeriksa bahwa perintah yang ditemukan di tabel hash ada sebelum mencoba untuk mengeksekusinya shopt -s checkhash

    help shopt mengatakan:

    checkhash - Jika diatur, bash memeriksa apakah ada perintah yang ditemukan di tabel hash sebelum mencoba untuk mengeksekusinya. Jika perintah hash tidak ada lagi, pencarian jalur normal dilakukan.

    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. Anda dapat mengikat NAME dengan PATH dengan hash -p PATH NAMEatau 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"tampilhash -r

    Dari variables.c:

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

    Mencoba:

    set -h
    hash -r
    date
    hash # prints 1 /bin/date
    PATH="$PATH"
    hash # prints hash: hash table empty

1
Saya tidak pernah mengerti mengapa semua mekanisme tambahan diberikan ketika PATH = $ PATH berfungsi dengan baik. Jika PATH berubah, maka cache pencarian PATH harus tidak valid. Masuk akal.
jrw32982

Kasus penggunaan tidak ditangani dengan membatalkan cache ketika perubahan PATH adalah ketika lokasi executable berubah. Ini bisa umum ketika Anda menggunakan shell untuk menambah atau menghapus program, hanya untuk membuatnya cache tempat terakhir menemukannya.
Adam

Bercak dengan tabel hash perintah adalah cara yang bagus untuk benar-benar membingungkan seseorang yang mencoba men-debug skrip bash.
Erik Aronesty

4

Seperti yang dicatat oleh pengguna johntex dalam komentar atas jawaban oleh pengguna Tobu , tindakan praktis paling sederhana di Bash adalah hanya mengulangi program Anda:

hash svnsync

Itu saja.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.