VagrantでLinux(CentOS)構築時に正しくソフトウェアをバージョンアップする方法  〜Python2.7からPython3.6へのバージョンアップの例を用いて〜


PATHとは?

Linuxに限らず、コマンドを実行する際にフルパスを書く必要がないのはPATHにそのパスの情報が保存されているからです。例えば、Linuxをシャットダウンする際に/usr/sbin/shutdown -h nowではなくshutdown -h nowと書いて実行できるのは、/usr/sbin/がPATHに登録されているからです。

PATHの確認方法

以下を実行。

echo $PATH

実行結果:

自分の場合、いじったのでこうなっています。PATHは何個でも登録してもよく、:で各パスに区切られています。

バージョンが違う同じソフトウェアを入れた時の対処

例えばCentOS7だとディフォルトでpython 2.7が入っています。python --versionを実行すると、そのバージョン情報が出てきます。
ここで、新たに以下のコマンドを叩きRed Hut Enterprise Linuxを使用してpython 3.6を落としてくるとします。

sudo yum -y install centos-release-scl;
sudo yum -y install rh-python36;
sudo scl enable rh-python36 bash;

この後にpython --versionを実行すると、python 3.6を見ていますが、Vagrantの操作等でパスを再度読み込んだ際に元に戻ってしまいます。これはRed Hut Enterprise Linuxで落としたpython 3.6/usr/binには行かずに/opt/rh/rh-python36/root/bin/へ落ちるためです。この/opt/rh/rh-python36/root/bin/をPATHへ登録し、/usr/binにあるpython2.7を取り除かない限りは綺麗にpythonのバージョンアップができません。ちなみにLinuxが参照しているpythonのパスは以下のコマンドでわかります。

which python

pythonに限らず、なんでもこのwhichでLinuxが参照しているコマンドの実際のパスがわかります。

python2.7など、古いバージョンのプログラムを取りのぞくときは、rmコマンドで削除するより、mvコマンドで名前を変えて取り置いといた方がいいです。以下Pythonの例をとった時のコマンドです。

sudo mv /usr/bin/python2.7 /usr/bin/python2.7_old

これでLinuxがPython2.7を退避することができます。

PATHの変更方法

いくつかあると思いますが、自分が好きなのはsourceコマンドで~/.bash_profileというファイルを取り込む方法です。~/.bash_profileにはPATHの情報があり、source ~/.bash_profileを実行することでPATH登録が行われます。シェルスクリプトでこれを実行する人に注意して欲しいんですが、この~がどこなのかスクリプト内に明記しておくべきです。というのもルートユーザーと一般ユーザーでは~の部分が違います(動画参照)。

Vagrantfileにシェルを仕込ませて実行した場合、~がどちらを向いてるか自分はわからなかった(vagrant provisionを行うと実行ユーザーはvagrantなのに~/root/側を見ているようだった)ので、明記しました。

結果、以下のコマンドでPATHを読み込ませました。

#/home/vagrant/.bash_profileにPATH情報を設定
echo "export PATH="/opt/rh/rh-python36/root/bin:/usr/bin:/usr/sbin"" >> /home/vagrant/.bash_profile;
#PATH情報を登録
source /home/vagrant/.bash_profile;

最後に

上記のステップを押さえておけば、どんなソフトウェアでも問題なくバージョンアップが可能です。
自分はsqlite 3.2sqlite 3.29へ同じアプローチでバージョンアップできました。

参考

https://teratail.com/questions/50308
https://qiita.com/nito128/items/e91e8510c882a7f24768