LinuxでPython3のバージョンを切り替え

今回は、LinuxサーバーでのPython3のバージョン切り替え方法について書きます。

はじめに

Python3.9を導入したLinuxサーバーのPythonバージョンを確認すると3.6となっていました。
最初はインストール失敗やPATHを疑ったのですが、どうやらそうではないようです。

■■■ Python3のバージョン確認 ■■■
$ python3 -V
Python 3.6.8
■■■ Pythonのバイナリ確認 ■■■
$ python3
python3                   python3.6m-config         python3.9-x86_64-config
python3.6                 python3.6m-x86_64-config  python3-config
python3.6-config          python3.9                 
python3.6m                python3.9-config     
[takamoto@Moselle ~]$ which python3.9
/usr/bin/python3.9
$ which python3.6
/usr/bin/python3.6
■■■ Python3の場所とPATH ■■■
$ which python3
/usr/bin/python3
$ printenv PATH
/home/takamoto/.local/bin:/usr/local/lib:/home/takamoto/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

結論としては、update-alternativesというコマンドでバージョンの切り替えができることがわかりましたので、情報共有します。

検証環境は以下となります。

  • OS:CentOS Linux release 8.3.2011
  • Python:Python3.6.8、3.9.6が共存

Python3はどこにあるのか

まずは、Python3の実体を確認してみましょう。

$ which python3
/usr/bin/python3
$ ls -l /usr/bin/python3
lrwxrwxrwx 1 root root 25 Jun  1  2020 /usr/bin/python3 -> /etc/alternatives/python3
$ ls -l /etc/alternatives/python3
lrwxrwxrwx 1 root root 18 Dec 15 07:15 /etc/alternatives/python3 -> /usr/bin/python3.6

わかったことは以下です。

  • python3は、/usr/bin/python3を指すシンボリックリンク
  • /usr/bin/python3は、/etc/alternatives/python3を指すシンボリックリンク
  • /etc/alternatives/python3は/、usr/bin/python3.6を指すシンボリックリンク

/etc/alternatives/を確認すると、javaやpostgresなどのバージョン管理が必要そうなプロダクトが確認できます。

$ ls /etc/alternatives/
cifs-idmap-plugin  ld                    pgsql-clusterdbman   pgsql-pg_basebackup     pip-3            print-lprman       rmiregistry
easy_install-3     libnssckbi.so.x86_64  pgsql-createdb       pgsql-pg_basebackupman  pip3             print-lprmman      rmiregistry.1.gz
ifdown             mta                   pgsql-createdbman    pgsql-pg_dump           policytool       print-lpstat       servertool
ifup               mta-mailq             pgsql-createlang     pgsql-pg_dumpall        policytool.1.gz  print-lpstatman    servertool.1.gz
java               mta-mailqman          pgsql-createlangman  pgsql-pg_dumpallman     print            pydoc-3            tnameserv
java.1.gz          mta-sendmail          pgsql-createuser     pgsql-pg_dumpman        print-cancel     pydoc3             tnameserv.1.gz
jjs                mta-sendmailman       pgsql-createuserman  pgsql-pg_restore        print-cancelman  python             unpack200
jjs.1.gz           orbd                  pgsql-dropdb         pgsql-pg_restoreman     print-lp         python3            unpack200.1.gz
jre                orbd.1.gz             pgsql-dropdbman      pgsql-psql              print-lpc        python3-config     unversioned-python-man
jre_1.8.0          pack200               pgsql-droplang       pgsql-psqlman           print-lpcman     python3-man
jre_1.8.0_openjdk  pack200.1.gz          pgsql-droplangman    pgsql-reindexdb         print-lpman      qtchooser-5
jre_openjdk        pax                   pgsql-dropuser       pgsql-reindexdbman      print-lpq        qtchooser-default
keytool            pax-man               pgsql-dropuserman    pgsql-vacuumdb          print-lpqman     rmid
keytool.1.gz       pgsql-clusterdb       pgsql-ld-conf        pgsql-vacuumdbman       print-lprm       rmid.1.gz

update-alternativesを使ったバージョン変更

シンボリックリンクを強引に書き換えようかとも思ったのですが、調べたところupdate-alternativesという便利なコマンドがありましたので使うことにします。

まずは状態を確認します。

$ update-alternatives --display python3
python3 - status is manual.
 link currently points to /usr/bin/python3.6
/usr/bin/python3.6 - priority 1000000
 slave easy_install-3: /usr/bin/easy_install-3.6
 slave pip-3: /usr/bin/pip-3.6
 slave pip3: /usr/bin/pip3.6
 slave pydoc-3: /usr/bin/pydoc3.6
 slave pydoc3: /usr/bin/pydoc3.6
 slave python3-config: /usr/bin/python3.6-config
 slave pyvenv-3: /usr/bin/pyvenv-3.6
 slave virtualenv: /usr/bin/virtualenv-3
 slave virtualenv-3: /usr/bin/virtualenv-3.6
 slave python3-man: /usr/share/man/man1/python3.6.1.gz
/usr/bin/python3.9 - priority 3900
 slave easy_install-3: /usr/bin/easy_install-3.9
 slave pip-3: /usr/bin/pip-3.9
 slave pip3: /usr/bin/pip3.9
 slave pydoc-3: /usr/bin/pydoc3.9
 slave pydoc3: /usr/bin/pydoc3.9
 slave python3-config: /usr/bin/python3.9-config
 slave pyvenv-3: (null)
 slave virtualenv: (null)
 slave virtualenv-3: (null)
 slave python3-man: /usr/share/man/man1/python3.9.1.gz
Current `best' version is /usr/bin/python3.6.

3.6がカレントのリンクとなっているので、3.9に変更します。

$ sudo update-alternatives --config python3

There are 2 programs which provide 'python3'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/bin/python3.6
   2           /usr/bin/python3.9

Enter to keep the current selection[+], or type selection number: 2
$ python3 -V
Python 3.9.6

Ubuntuの場合

後日、UbuntuにてPythonのバージョンアップを実施しようとしましたが、以下のようにupdate-alternativesの管理下にないとのエラーとなりました。

$ python3
Python 3.8.10
$ sudo update-alternatives --config python3
update-alternatives: error: no alternatives for python3

CentOSとUbuntuの違いなのだと思いますが、まずはpython3のパスを確認します。

$ which python3
/usr/bin/python3
$ ls -l /usr/bin/python*
lrwxrwxrwx 1 root root       9 Mar 13  2020 /usr/bin/python3 -> python3.8
lrwxrwxrwx 1 root root      16 Mar 13  2020 /usr/bin/python3-config -> python3.8-config
-rwxr-xr-x 1 root root 5490488 Nov 26 20:14 /usr/bin/python3.8
lrwxrwxrwx 1 root root      33 Nov 26 20:14 /usr/bin/python3.8-config -> x86_64-linux-gnu-python3.8-config
-rwxr-xr-x 1 root root 5803968 Nov 23 15:27 /usr/bin/python3.9

続いて、update-alternatives --install を使って新規に登録します。

$ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 1
update-alternatives: using /usr/bin/python3.9 to provide /usr/bin/python3 (python3) in auto mode
$ sudo update-alternatives --config python3
There is 1 choice for the alternative python3 (providing /usr/bin/python3).

  Selection    Path                Priority   Status
------------------------------------------------------------
* 0            /usr/bin/python3.9   1         auto mode
  1            /usr/bin/python3.9   1         manual mode

Press <enter> to keep the current choice[*], or type selection number: 
$ python3 -V
Python 3.9.5

pipについては、apt install にてインストールしました。

$ sudo apt install python3-pip
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  python3-pip
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 231 kB of archives.
After this operation, 1050 kB of additional disk space will be used.
Get:1 http://ap-northeast-1.ec2.archive.ubuntu.com/ubuntu focal-updates/universe amd64 python3-pip all 20.0.2-5ubuntu1.6 [231 kB]
Fetched 231 kB in 2s (153 kB/s)      
Selecting previously unselected package python3-pip.
(Reading database ... 171591 files and directories currently installed.)
Preparing to unpack .../python3-pip_20.0.2-5ubuntu1.6_all.deb ...
Unpacking python3-pip (20.0.2-5ubuntu1.6) ...
Setting up python3-pip (20.0.2-5ubuntu1.6) ...
Processing triggers for man-db (2.9.1-1) ...
$ pip3 -V
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.9)

まとめ

update-alternativesは、とても便利な仕組みだと感じました。

また、OSのディストリビューションもしくはインストーラの違いによって、update-alternativesの使用/未使用があることもわかりました。

ちょっと勉強になりました。