WSL2環境でpyenvのPython動かせるようにしようとしたときに少しハマったので解決するまでの手順を紹介します。
前提
- Windows11
- Windows側にpyenv導入済み
- WSL2未導入
WSL2をインストールする
公式サイトを参考にしました。
一昔前まではあれやこれややる必要があった気がしたのですが、今はwsl --install
一発でインストールできるようになっているんですね。
PS > wsl --install
インストール中: Linux 用 Windows サブシステム
Linux 用 Windows サブシステム はインストールされました。
インストール中: Ubuntu
Ubuntu はインストールされました。
要求された操作は正常に終了しました。変更を有効にするには、システムを再起動する必要があります。
再起動しろと言われたので再起動したところ、勝手にUbuntuが立ち上がってusernameとかの設定をさせられました。
Ubuntu は既にインストールされています。
Ubuntu を起動しています...
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username: ubuntu
New password:
Retype new password:
passwd: password updated successfully
この操作を正しく終了しました。
Installation successful!
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.133.1-microsoft-standard-WSL2 x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
This message is shown once a day. To disable it please create the
/home/ubuntu/.hushlogin file.
ubuntu@vivobook16x:~$
usernameとパスワードを設定するとubuntuが立ち上がりました。
現時点ではデフォルトでUbuntu22.04が選択されるようです。
一度Ubuntuからログアウトして、PSからWSLのバージョンを確認します。
PS > wsl --version
WSL バージョン: 2.0.9.0
カーネル バージョン: 5.15.133.1-1
WSLg バージョン: 1.0.59
MSRDC バージョン: 1.2.4677
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22621.3007
インストールするのがWSL1なのかWSL2なのかを特に指定していないのですが、WSL2がデフォルトでインストールされるみたいですね。
一応WSLのアップデートをしておきます。
PS > wsl --update
更新プログラムを確認しています。
Linux 用 Windows サブシステムをバージョンに更新しています: 2.0.14。
要求された操作には管理者特権が必要です。
更新プログラムを確認しています。
Linux 用 Windows サブシステムをバージョンに更新しています: 2.0.14。
PS > wsl --version
WSL バージョン: 2.0.14.0
カーネル バージョン: 5.15.133.1-1
WSLg バージョン: 1.0.59
MSRDC バージョン: 1.2.4677
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22621.3007
これでWSLの準備は完了です。
pyenvのインストール
こちらも公式Githubを参照しました。
まずwsl
コマンドでUbuntuへログインします。
そのあとホームディレクトリへ移動して、aptのアップデートとアップグレードをしておきます。
PS > wsl
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
$ cd ~
$ sudo apt update
$ sudo apt upgrade -y
このUbuntuにはPython3.10.12がプリインストールされているようです。参照先もWindowsではなくUbuntu内ですね。
$ python3 -V
Python 3.10.12
$ which python3
/usr/bin/python3
pyenvの公式GithubによるとUbuntuへのインストールは↓の4行でできるようです。
$ curl https://pyenv.run | bash
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
この後、.bashrcへ書き込んだ内容を有効化するためにsource ~/.bashrc
を打ち込みますが、ここでエラーが発生します。
$ source .bashrc
/mnt/c/Users/***/.pyenv/pyenv-win/bin/pyenv: 3: cygpath: not found
/mnt/c/Users/***/.pyenv/pyenv-win/bin/pyenv: 3: exec: cmd: not found
見た感じpyenv
コマンドがWindows側のpyenvを見に行ってしまっているようです。
which pyenv
で調べるとやはりWindowsにインストールされたpyenvを参照していますね。
$PATH
の中身を確認しますと、どうやらUbuntuの環境変数にはWindowsの環境変数も設定されているみたいです。
$ which pyenv
/mnt/c/Users/***/.pyenv/pyenv-win/bin/pyenv
$ echo $PATH
(略):/mnt/c/Users/***/.pyenv/pyenv-win/bin:/mnt/c/Users/***/.pyenv/pyenv-win/shims:(略)
これが今回の不具合にどのような影響を及ぼしているのかというと、Ubuntuへpyenvをインストールした際に.bashrc
へ追記した
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
が正しく動かなくなることにつながります。
この行がざっくり何をしているのかというと、「pyenv
コマンドを参照できない場合に今回インストールしたpyenvのPATHを環境変数に追加する」です。
通常はpyenv
コマンドはまだ参照できないはずなので、インストールされたpyenvのPATHが環境変数に追加されることになります。
しかし、今回すでにWindows側にpyenvが導入されていてUbuntuがWindowsの環境変数を見ているとなりますと「pyenv
コマンドを参照できる」と判断されてしまい、Ubuntu用にインストールされたpyenvのPATHが環境変数へ追加されないことになってしまっていたのです。
したがって今回は↓のように、~/.bashrc
内の記述を変更して四の五の言わずにUbuntu用のpyenvのPATHを追加するようにしました。
(略)
command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
(略)
(略)
export PATH="$PYENV_ROOT/bin:$PATH"
(略)
その後、設定を反映するためにsource ~/.bashrc
を打ち込めばインストール完了です。
$ source ~/.bashrc
$ which pyenv
/home/ubuntu/.pyenv/bin/pyenv
$ pyenv --version
pyenv 2.3.35
ちなみにWindows側もバグりません。
$ exit
logout
PS > pyenv --version
pyenv 3.1.1
これで、WindowsとWSL2それぞれにpyenvが存在したときの衝突回避が無事に完了しました。