Tại sao `type which` nói rằng` được băm`?


31

Trong trường hợp shell-buildins (ví dụ: typechính nó):

$ type type
type is a shell builtin

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

Trong trường hợp các lệnh (thông thường) (ví dụ python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

Trong trường hợp which(đó là một lệnh nằm ở /usr/bin/which)

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

Tại sao type whichnói vậy which is hashed? Tầm quan trọng của whichviệc được băm và ý nghĩa thực sự của nó là gì?

Câu trả lời:


40

Bạn có thể có một bộ PATH dài và, để tìm một tệp thực thi, trình bao cần tìm kiếm đường dẫn. Để tránh quá trình tốn thời gian đó mỗi khi bạn muốn chạy một chương trình, trình bao có thể giữ một danh sách các chương trình mà nó đã tìm thấy. Danh sách đó được gọi là "băm." Khi shell nói rằng nó whichđược băm, điều đó có nghĩa là nó đã thực hiện tìm kiếm PATH và tìm thấy whichvà lưu vị trí của nó trong hàm băm.

man bash giải thích nó như sau:

Bash sử dụng bảng băm để ghi nhớ tên đường dẫn đầy đủ của các tệp thực thi (xem hàm băm dưới SHELL BUILTIN THÔNG TIN bên dưới). Một tìm kiếm đầy đủ của các thư mục trong PATH chỉ được thực hiện nếu không tìm thấy lệnh trong bảng băm.

Mặc dù hàm băm thường tăng tốc hoạt động của vỏ, có một trường hợp gây ra sự cố. Nếu bạn cập nhật hệ thống của mình và do đó, một số di chuyển thực thi đến một vị trí mới, trình bao có thể bị nhầm lẫn. Giải pháp là chạy hash -rkhiến cho vỏ bị quên tất cả các vị trí được băm và tìm kiếm PATH từ đầu.

Tại sao một số thực thi bị thiếu từ hàm băm?

Một tệp thực thi không được đặt trong hàm băm cho đến sau khi bạn thực thi ít nhất một lần. Quan sát:

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

python chỉ được băm sau khi nó được thực thi.

Làm thế nào để kiểm tra những gì trong bash của bash

Nội dung của hàm băm có sẵn trong bashmảng BASH_CMDS. Bạn có thể thấy những gì trong đó với lệnh declare -p BASH_CMDS. Khi một shell hoặc subshell mới được mở, hàm băm trống. Các lệnh được thêm từng cái một khi chúng được sử dụng. Từ một vỏ mới mở, quan sát:

$ 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" )'

+1, giải thích khá tốt. Nhưng tại sao cho whichvà không cho python?
việc

@Jobin Xem câu trả lời cập nhật.
John1024

2
Có vẻ như hàm băm chỉ tồn tại cho đến khi chúng ta không thoát khỏi vỏ. Khi chúng tôi khởi động lại thiết bị đầu cuối, nó không nói rằng lệnh được băm.
Aditya

1
@Aditya Có. Tôi đã thêm một phần vào đó để trả lời.
John1024

hash -lsẽ dễ sử dụng hơndeclare -p BASH_CMDS
phuclv
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.