プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

WSL2 の環境で python コマンドが使えたり使えなかったりする謎について

前々から、 WSL2 で python を使う時は pyenv + venv で python 環境を扱っています。

さて、わざわざプロジェクトフォルダを作ったうえで、

pyenv local 3.xx

のようにバージョンを指定せずに使いたい時も結構あります。そのようなときに、 python を起動しようとすると

mor@DESKTOP-DE7IL4F:~$ python
pyenv: python: command not found

The `python' command exists in these Python versions:
  3.11.4
  3.13.1

Note: See 'pyenv help global' for tips on allowing both
      python2 and python3 to be found.
mor@DESKTOP-DE7IL4F:~$

のようになることがあります。でも、場合によっては python でちゃんと起動できるときもあります。

この動作がちょっと気持ち悪かったので、何が問題なのか調べてみました。

問題を把握

さて、うまくいく時といかない時にどのような違いがあるのか、いろいろと試してみると

mor@DESKTOP-DE7IL4F:~/tmp/no_python_version$ pyenv version
system (set by /home/mor/.pyenv/version)
mor@DESKTOP-DE7IL4F:~/tmp/no_python_version$

のようにシステムの python を使うとなっているフォルダで発生していました。

一方、 pyenv local でバージョンを指定したフォルダの場合は、

mor@DESKTOP-DE7IL4F:~/tmp/exist_python_version$ pyenv version
3.13.1 (set by /home/mor/tmp/exist_python_version/.python-version)
mor@DESKTOP-DE7IL4F:~/tmp/exist_python_version$ python --version
Python 3.13.1
mor@DESKTOP-DE7IL4F:~/tmp/exist_python_version$

のように期待通りに動いています。どういうことだ?

このままだとわからないので python の本体がどこにあるか調べてみます。

mor@DESKTOP-DE7IL4F:~/tmp/exist_python_version$ which python
/home/mor/.pyenv/shims/python
mor@DESKTOP-DE7IL4F:~/tmp/exist_python_version$

pyenv の環境内ですね。pyenv 指定がないほうも、

mor@DESKTOP-DE7IL4F:~/tmp/no_python_version$ which python
/home/mor/.pyenv/shims/python
mor@DESKTOP-DE7IL4F:~/tmp/no_python_version$

同じですね。というか、 pyenv によりこのファイルを呼び出すようになっているんですよね。

pyenv の動作

ということで改めて pyenv の動作を確認してみます。

pyenvはどのようにバージョンを切り替えているのか? #Python - Qiita

こちらのブログの記事などを読むとわかりやすかったです。雑にまとめると

PYENV_VERSION 環境変数 ---> ローカルにある .python-version ファイル ---> 親ディレクトリの .python-version ファイル ---> global の設定値 ---> sysytem

という順で決まるそうです。pyenv version での表示と一致しているし、へんな感じじゃないですね。

解決

ふと思い出したのですが、 python って python2 とか python3 とかで起動することもありますよね。あれっていつ頃から python で python3 を起動するようになったんだろうか?と思い立って調べてみると、なんと、いまの Ubuntu (24.04) とかには python3 のみがインストールされていて python は入っていないとのことです。

Ubuntuで「python」コマンドが見つからない理由と解決方法 | LFI

で、昔は python2 と python が入っていて、 python が python2 を指していたとのこと。

しかも、いまは python で python3 を起動したければ、自分でaliasを張ったり、 python-is-python3 パッケージというのをインストールするという方法をとるそうです。

あ、きっとこれですね。おぼろげながら使っているんで、いろんな記憶がごちゃまぜになって、 python コマンドが普通にあると思ってました。

というわけで、pyenv をインストールすると、

  • ~/.pyenv/shims に python がインストールされる
  • pyenv local でバージョンが割り当てられているる場合は、そちらの python が呼び出される
  • system の場合も同様
  • でも、システムには python コマンドがない

という流れのような気がします。実際 pyenv でインストールしたほうの python を見てみると

mor@DESKTOP-DE7IL4F:~/.pyenv/versions/3.13.1/bin$ ls -l python*
lrwxrwxrwx 1 mor mor    10 1212  2024 python -> python3.13
lrwxrwxrwx 1 mor mor    17 1212  2024 python-config -> python3.13-config
lrwxrwxrwx 1 mor mor    10 1212  2024 python3 -> python3.13
lrwxrwxrwx 1 mor mor    17 1212  2024 python3-config -> python3.13-config
-rwxr-xr-x 1 mor mor 17704 1212  2024 python3.13
-rwxr-xr-x 1 mor mor  3339 1212  2024 python3.13-config
-rwxr-xr-x 1 mor mor 70581 1212  2024 python3.13-gdb.py
mor@DESKTOP-DE7IL4F:~/.pyenv/versions/3.13.1/bin$

のように ~/.pyenv/versions/(バージョン番号)/bin の配下に python がシンボリックリンクとして作られていました。

一方、システムの /usr/bin を見てみると、

mor@DESKTOP-DE7IL4F:/usr/bin$ ls -l python*
-rwxr-xr-x 1 root root    2640  83  2024 python-argcomplete-check-easy-install-script
lrwxrwxrwx 1 root root      10 1112 21:15 python3 -> python3.12
lrwxrwxrwx 1 root root      17 1112 21:15 python3-config -> python3.12-config
-rwxr-xr-x 1 root root 8020928  18 20:30 python3.12
lrwxrwxrwx 1 root root      34  18 20:30 python3.12-config -> x86_64-linux-gnu-python3.12-config
mor@DESKTOP-DE7IL4F:/usr/bin$

となっており、 python はない状態です。

テスト

ということで、試してみます。

mor@DESKTOP-DE7IL4F:~$ sudo apt install python-is-python3

として、 python-is-python3 パッケージをインストールします。その後

mor@DESKTOP-DE7IL4F:~/tmp/no_python_version$ ls -laF
合計 8
drwxr-xr-x  2 mor mor 4096  130 15:39 ./
drwxr-xr-x 22 mor mor 4096  130 15:41 ../
mor@DESKTOP-DE7IL4F:~/tmp/no_python_version$ pyenv version
system (set by /home/mor/.pyenv/version)
mor@DESKTOP-DE7IL4F:~/tmp/no_python_version$ python --version
Python 3.12.3
mor@DESKTOP-DE7IL4F:~/tmp/no_python_version$

解決できましたね。念のために /usr/bin もみてみると

mor@DESKTOP-DE7IL4F:/usr/bin$ ls -l python*
lrwxrwxrwx 1 root root       7  613  2023 python -> python3
-rwxr-xr-x 1 root root    2640  83  2024 python-argcomplete-check-easy-install-script
lrwxrwxrwx 1 root root      10 1112 21:15 python3 -> python3.12
lrwxrwxrwx 1 root root      17 1112 21:15 python3-config -> python3.12-config
-rwxr-xr-x 1 root root 8020928  18 20:30 python3.12
lrwxrwxrwx 1 root root      34  18 20:30 python3.12-config -> x86_64-linux-gnu-python3.12-config
mor@DESKTOP-DE7IL4F:/usr/bin$

ちゃんと python が入っていました。

まとめ

ちょっとしたことですが、システムにデフォルトで python が入っていないということを知らなかったばっかりに、時間を費やしてしまいました。まずは一件落着です。