Mengapa `ketik yang` mengatakan bahwa` yang hash`?

31

Dalam hal shell-builtin (mis. Dirinya typesendiri):

$ type type
type is a shell builtin

$ which type
<Doesn't return anything since it's a shell builtin, silently exits>

Dalam hal perintah (biasanya) (misalnya python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

Dalam hal which(yang merupakan perintah terletak di /usr/bin/which)

$ type which
which is hashed (/usr/bin/which)
$ which which
/usr/bin/which

Mengapa type whichdikatakan demikian which is hashed? Apa pentingnya whichhash dan apa artinya sebenarnya?

Aditya
sumber

Jawaban:

40

Anda mungkin memiliki set PATH yang panjang dan, untuk menemukan yang dapat dieksekusi, shell perlu mencari path. Untuk menghindari proses yang memakan waktu itu setiap kali Anda ingin menjalankan suatu program, shell dapat menyimpan daftar program yang telah ditemukannya. Daftar itu disebut "hash." Ketika shell mengatakan bahwa whichhash, itu berarti bahwa ia telah melakukan pencarian PATH dan menemukan whichdan menyimpan lokasinya di hash.

man bash menjelaskannya sebagai berikut:

Bash menggunakan tabel hash untuk mengingat nama path lengkap dari file yang dapat dieksekusi (lihat hash di bawah SHELL BUILTIN PERINTAH di bawah). Pencarian penuh direktori di PATH dilakukan hanya jika perintah tidak ditemukan di tabel hash.

Sementara hash biasanya mempercepat operasi shell, ada satu kasus di mana ia menyebabkan masalah. Jika Anda memperbarui sistem Anda dan, sebagai akibatnya, beberapa bergerak yang dapat dieksekusi ke lokasi baru, shell mungkin menjadi bingung. Solusinya adalah menjalankan hash -ryang menyebabkan shell melupakan semua lokasi hash dan mencari PATH dari awal.

Mengapa beberapa executable hilang dari hash?

Eksekusi tidak ditempatkan dalam hash sampai setelah Anda mengeksekusi setidaknya sekali. Mengamati:

$ type python
python is /usr/bin/python
$ python --version
Python 2.7.3
$ type python
python is hashed (/usr/bin/python)

python hash hanya setelah dieksekusi.

Cara memeriksa apa yang ada di hash bash

Isi hash tersedia dalam basharray BASH_CMDS. Anda dapat melihat apa yang ada di dalamnya dengan perintah declare -p BASH_CMDS. Ketika shell atau subkulit baru dibuka, hash kosong. Perintah ditambahkan satu per satu saat digunakan. Dari cangkang yang baru dibuka, amati:

$ declare -p BASH_CMDS
declare -A BASH_CMDS='()'
$ which which
/bin/which
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" )'
$ python --version
Python 2.7.3
$ declare -p BASH_CMDS
declare -A BASH_CMDS='([which]="/bin/which" [python]="/usr/bin/python" )'
John1024
sumber
+1, penjelasan yang cukup bagus. Tetapi mengapa untuk whichdan bukan untuk python?
jobin
@ Bobob Lihat jawaban yang diperbarui.
John1024
2
Sepertinya hash hanya bertahan sampai waktu kita tidak keluar dari shell. Setelah kita me-restart terminal, itu tidak mengatakan bahwa perintah di-hash.
Aditya
1
@Aditya Ya. Saya menambahkan bagian tentang itu ke jawabannya.
John1024
hash -lakan lebih mudah digunakan daripadadeclare -p BASH_CMDS
phuclv