「type which」は「which is hashed」と言うのはなぜですか?


31

シェル組み込みの場合(例えば、typeそれ自体):

$ type type
type is a shell builtin

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

コマンドの場合(通常)(例python):

$ type python
python is /usr/bin/python

$ which python
/usr/bin/python

の場合which(これはにあるコマンドです/usr/bin/which

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

なんでtype whichそんなこと言うのwhich is hashedwhichハッシュされることの重要性は何ですか、実際にはどういう意味ですか?

回答:


40

長いPATHが設定されている可能性が高く、実行可能ファイルを見つけるには、シェルがパスを検索する必要があります。プログラムを実行するたびにその時間のかかるプロセスを回避するために、シェルは既に見つかったプログラムのリストを保持する場合があります。そのリストは「ハッシュ」と呼ばれます。シェルwhichがハッシュされていると言うとき、それはすでにPATH検索を実行whichし、ハッシュ内でその場所を見つけて保存したことを意味します。

man bash 次のように説明します。

Bashはハッシュテーブルを使用して、実行可能ファイルのフルパス名を記憶します(以下のSHELL BUILTINコマンドのハッシュを参照)。PATH内のディレクトリの完全検索は、コマンドがハッシュテーブルで見つからない場合にのみ実行されます。

ハッシュは通常、シェル操作を高速化しますが、問題を引き起こすケースが1つあります。システムを更新し、その結果、一部の実行可能ファイルが新しい場所に移動すると、シェルが混乱する可能性があります。解決策はhash -r、シェルがすべてのハッシュされた場所を忘れ、PATHを最初から検索するように実行することです。

一部の実行可能ファイルがハッシュから欠落しているのはなぜですか?

少なくとも1回実行するまで、実行可能ファイルはハッシュに配置されません。観察する:

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

python 実行された後にのみハッシュされます。

bashのハッシュの内容を調べる方法

ハッシュの内容はbash配列で利用可能ですBASH_CMDS。コマンドでその中身を確認できますdeclare -p BASH_CMDS。新しいシェルまたはサブシェルが開かれると、ハッシュは空になります。コマンドは使用されるたびに1つずつ追加されます。新しく開いたシェルから、次を観察します。

$ 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、かなり良い説明。しかし、なぜのためにwhich、ではないのpythonですか?
jobin 14

@Jobin最新の回答をご覧ください。
John1024 14

2
ハッシュは、シェルを終了しない限り持続するようです。ターミナルを再起動すると、コマンドがハッシュされているとは言いません。
アディティア14

1
@Adityaはい。それに関するセクションを回答に追加しました。
ジョン1024 14

hash -ldeclare -p BASH_CMDS
phuclv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.