alternatives コマンドによる複数バージョンの使い分け

はじめに

AmazonLinuxでは、各種ソフトウェアが複数バージョンで用意されている事が多いです。
一例を上げると、Java,ruby,python などがあります。

[root@ip-172-31-11-130 ~]# ruby
ruby     ruby2.0  ruby2.3
[root@ip-172-31-11-130 ~]# ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux-gnu]
[root@ip-172-31-11-130 ~]#

この場合、ruby2.3をアンインストールしないと /usr/bin/ruby を使って ruby2.0 が使えないのかというとそんなことはありません。

alternatives コマンドによる切り替え

[root@ip-172-31-11-130 ~]# ll /usr/bin/ruby*
lrwxrwxrwx 1 root root   22 Jun 10 16:26 /usr/bin/ruby -> /etc/alternatives/ruby
-rwxr-xr-x 1 root root 5592 Jan 14 21:04 /usr/bin/ruby2.0
-rwxr-xr-x 1 root root 5576 Feb 24 22:23 /usr/bin/ruby2.3
[root@ip-172-31-11-130 ~]# ll /etc/alternatives/ruby
lrwxrwxrwx 1 root root 16 Jun 10 16:26 /etc/alternatives/ruby -> /usr/bin/ruby2.3
[root@ip-172-31-11-130 ~]#

このコマンド結果の通り、シンボリックリンクで実体の向け先を変えている事がわかります。 この向け先変更を行うコマンドが alternatives です。

類似するソフトウェアの切り替えなどで使われていましたが、こういうケースでも利用出来ます(sendmail,postfixの切り替えなど)。

変更方法

今回試しているAmazonLinuxの環境では、ruby2.0とruby2.3のパッケージをインストールしています。

[root@ip-172-31-11-130 ~]# alternatives --display ruby
ruby - status is manual.
 link currently points to /usr/bin/ruby2.3
/usr/bin/ruby2.0 - priority 2000
 slave erb: /usr/bin/erb2.0
 slave gem: /usr/bin/gem2.0
 slave irb: /usr/bin/irb2.0
 slave rake: /usr/bin/rake2.0
 slave rdoc: /usr/bin/rdoc2.0
 slave ri: /usr/bin/ri2.0
 slave testrb: /usr/bin/testrb2.0
 slave ruby.pc: /usr/lib64/pkgconfig/ruby-2.0.pc
 slave erb.1: /usr/share/man/man1/erb2.0.1.gz
 slave irb.1: /usr/share/man/man1/irb2.0.1.gz
 slave rake.1: /usr/share/man/man1/rake2.0.1.gz
 slave ri.1: /usr/share/man/man1/ri2.0.1.gz
 slave ruby.1: /usr/share/man/man1/ruby2.0.1.gz
/usr/bin/ruby2.3 - priority 230
 slave erb: /usr/bin/erb2.3
 slave gem: /usr/bin/gem2.3
 slave irb: /usr/bin/irb2.3
 slave rake: /usr/bin/rake2.3
 slave rdoc: /usr/bin/rdoc2.3
 slave ri: /usr/bin/ri2.3
 slave testrb: (null)
 slave ruby.pc: /usr/lib64/pkgconfig/ruby-2.3.pc
 slave erb.1: /usr/share/man/man1/erb2.3.1.gz
 slave irb.1: /usr/share/man/man1/irb2.3.1.gz
 slave rake.1: /usr/share/man/man1/rake2.3.1.gz
 slave ri.1: /usr/share/man/man1/ri2.3.1.gz
 slave ruby.1: /usr/share/man/man1/ruby2.3.1.gz
Current `best' version is /usr/bin/ruby2.0.
[root@ip-172-31-11-130 ~]#

--display でどちらのrubyが使われているかがわかります。また、表示されているように各種ライブラリなども切り替わります。gemもちゃんと切り替わってくれるので安心ですね。

[root@ip-172-31-11-130 ~]# alternatives --config ruby

There are 2 programs which provide 'ruby'.

  Selection    Command
-----------------------------------------------
*  1           /usr/bin/ruby2.0
 + 2           /usr/bin/ruby2.3

Enter to keep the current selection[+], or type selection number: 1
[root@ip-172-31-11-130 ~]#

--config で切り替える事が出来ます。

[root@ip-172-31-11-130 ~]# ruby -v
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
[root@ip-172-31-11-130 ~]#

ちゃんとバージョンが変わっていますね。
ちなみに、--display で再度確認してみると全て切り替わっている事が分かります。

[root@ip-172-31-11-130 ~]# alternatives --display ruby
ruby - status is manual.
 link currently points to /usr/bin/ruby2.0
/usr/bin/ruby2.0 - priority 2000
 slave erb: /usr/bin/erb2.0
 slave gem: /usr/bin/gem2.0
 slave irb: /usr/bin/irb2.0
 slave rake: /usr/bin/rake2.0
 slave rdoc: /usr/bin/rdoc2.0
 slave ri: /usr/bin/ri2.0
 slave testrb: /usr/bin/testrb2.0
 slave ruby.pc: /usr/lib64/pkgconfig/ruby-2.0.pc
 slave erb.1: /usr/share/man/man1/erb2.0.1.gz
 slave irb.1: /usr/share/man/man1/irb2.0.1.gz
 slave rake.1: /usr/share/man/man1/rake2.0.1.gz
 slave ri.1: /usr/share/man/man1/ri2.0.1.gz
 slave ruby.1: /usr/share/man/man1/ruby2.0.1.gz
/usr/bin/ruby2.3 - priority 230
 slave erb: /usr/bin/erb2.3
 slave gem: /usr/bin/gem2.3
 slave irb: /usr/bin/irb2.3
 slave rake: /usr/bin/rake2.3
 slave rdoc: /usr/bin/rdoc2.3
 slave ri: /usr/bin/ri2.3
 slave testrb: (null)
 slave ruby.pc: /usr/lib64/pkgconfig/ruby-2.3.pc
 slave erb.1: /usr/share/man/man1/erb2.3.1.gz
 slave irb.1: /usr/share/man/man1/irb2.3.1.gz
 slave rake.1: /usr/share/man/man1/rake2.3.1.gz
 slave ri.1: /usr/share/man/man1/ri2.3.1.gz
 slave ruby.1: /usr/share/man/man1/ruby2.3.1.gz
Current `best' version is /usr/bin/ruby2.0.
[root@ip-172-31-11-130 ~]#

まとめ

AmazonLinuxのパッケージを利用したメジャーバージョンアップでも使えるかもしれないですね。 なお、自分でビルドしたrubyパッケージを対象にしたい場合は自分で管理対象に追加する必要があります。

詳しくは、下記参考ページがとても詳細に解説されています。 alternatives による標準コマンドの切り替え