シンボリックリンクは正しいバイナリを指していますが、それでも別のものが実行されますか?

シンボリックリンクは正しいバイナリを指していますが、それでも別のものが実行されますか?

これがどのように可能なのか、少し混乱しています。Python の新しいバージョンをインストールし、古いシンボリックリンクを削除して新しいものに置き換えました。しかし、何らかの理由で、古いバイナリがまだ呼び出されるのでしょうか?

pi@raspberrypi:/usr/local/bin$ python -V
Python 3.7.3
pi@raspberrypi:/usr/local/bin$ which python
/usr/local/bin/python
pi@raspberrypi:/usr/local/bin$ ls -l /usr/local/bin/python
lrwxrwxrwx 1 root root 24 Feb 19 17:37 /usr/local/bin/python -> /usr/local/bin/python3.9
pi@raspberrypi:/usr/local/bin$ /usr/local/bin/python -V
Python 3.9.9
pi@raspberrypi:/usr/local/bin$ readlink python
/usr/local/bin/python3.9

この動作を説明できる人はいますか? 何か間違ったことをしたのでしょうか?

答え1

command -vの代わりにを使用することをお勧めしますwhich。その理由については、このUnix SE Q/Aで短いバージョン:は、whichはるか昔の非標準ツールです。command -vはシェルの組み込みコマンドであり、POSIX 標準です。Bourne シェルでは、typeまたは を使用する必要がありますcommand -v

すでにお分かりのように、エイリアスはシェル組み込みでのみ検出できる可能性のあるケースの 1 つです。次に例を示します。

$ alias
alias ls='ls --color=auto'
$ type ls
ls is aliased to `ls --color=auto'
$ command -v ls
alias ls='ls --color=auto'
$ which ls
/bin/ls

あなたの場合、pythonは にエイリアスされているようですpython3。エイリアスを定義できる場所はたくさんあります。

答え2

Python を一度 1 か所にインストールしました。その後、シンボリック リンクを別の場所に変更しました。

結果をメモリにキャッシュすることで、コマンドを入力するたびに $PATH を検索する必要がないようにする bash の最適化に遭遇したと思います。

パスハッシュは、bashによって管理されるハッシュテーブルで、コマンド実行時にシェルが実行可能プログラムを探すディスク上の場所が含まれています。ハッシュテーブルは、明らかに結果を無効にするイベント($PATHの変更など)でクリアされるか、組み込みの ハッシュ 指示。

再度 python を実行すると、bash は前回見つけた場所から取得しようとしたため、古いバージョンが取得されました。

Python のハッシュを無効にするには、次のいずれかのコマンドを実行します。

hash python
hash -r

関連情報