Monday, March 07, 2016

Creating alternatives

Something much bigger I'm probably gearing up to document here (if it works out, since I'm still trying to determine if I've been wasting my time learning this tool or not) inspired me to again check the manpages on a pretty useful little tool:  update-alternatives.

It's nothing terribly special, it gets used everywhere, and it's not very difficult to use, but I don't use it as often as I should, to be honest.

Today I found myself needing to install a new version of ruby on my system.  On an ageing (seriously?  8.2 is ageing?) Debian system like mine that's an interesting level of hell that I'll also get into at a later date not because I ever expect to do that particular dance again nor do I expect anyone else to be interested in it, but because it helped me get the rust out of some gears that I find myself needing to turn reasonably often, so the how is interesting even if the what or why are not.

But back to the quickie for today.

update-alternatives lets you have multiple versions of the same executable (or, to a lesser extent, libraries / manuals / shared files / etc.) installed on a system at the same time and identify the one you want to use by default.  So, for example, I use mutt for email.  But which mutt?

# which mutt
/usr/bin/mutt
# ls -l /usr/bin/mutt
lrwxrwxrwx 1 root 22 Oct 25  2013 /usr/bin/mutt -> /etc/alternatives/mutt*
# update-alternatives --list mutt
/usr/bin/mutt-org
/usr/bin/mutt-patched

So from that you can see that I've got two different versions of mutt, but when I type mutt I get mutt-patched.  If I wanted to change that, though, and run the vanilla mutt.org version of mutt, I could just change the alternative to point at mutt-org instead with a command like:

# update-alternatives --config mutt
There are 2 choices for the alternative mutt (providing /usr/bin/mutt).

  Selection    Path                   Priority   Status
------------------------------------------------------------
* 0            /usr/bin/mutt-patched   60        auto mode
  1            /usr/bin/mutt-org       50        manual mode
  2            /usr/bin/mutt-patched   60        manual mode

Press enter to keep the current choice[*], or type selection number: 
#

That's good, but when I started out today there were no alternatives for ruby. Irritating, since /usr/bin/ruby was already a symlink to one of three (!) versions already installed, but there was no update-alternatives mechanism to switch (and, of course, my new ruby just landed in the same spot and wouldn't actually get used when I invoked ruby --version, so that didn't solve my problem anyway...). It turns out, though, that update-alternatives does exactly the right thing.

# update-alternatives --list ruby  
update-alternatives: error: no alternatives for ruby
# ls -l /usr/bin/ruby*
lrwxrwxrwx 1 root    7 May 10  2015 /usr/bin/ruby -> ruby2.1*
-rwxr-xr-x 1 root 6264 Dec  1  2013 /usr/bin/ruby1.8*
-rwxr-xr-x 1 root 6336 Feb  8  2015 /usr/bin/ruby1.9.1*
-rwxr-xr-x 1 root 6168 Aug 26  2015 /usr/bin/ruby2.1*
# update-alternatives --install /usr/bin/ruby ruby /usr/bin/ruby2.1 100
update-alternatives: using /usr/bin/ruby2.1 to provide /usr/bin/ruby (ruby) in auto mode
# update-alternatives --install /usr/bin/ruby ruby /usr/bin/ruby1.9.1 50 
# update-alternatives --install /usr/bin/ruby ruby /usr/bin/ruby1.8 40  
# update-alternatives --list ruby                                            
/usr/bin/ruby1.8
/usr/bin/ruby1.9.1
/usr/bin/ruby2.1
# update-alternatives --config ruby
There are 3 choices for the alternative ruby (providing /usr/bin/ruby).

  Selection    Path                Priority   Status
------------------------------------------------------------
* 0            /usr/bin/ruby2.1     100       auto mode
  1            /usr/bin/ruby1.8     40        manual mode
  2            /usr/bin/ruby1.9.1   50        manual mode
  3            /usr/bin/ruby2.1     100       manual mode

Press enter to keep the current choice[*], or type selection number: 
#

The numbers I assigned are purely relative, they don't mean anything except that the preferred version will be the one that was previously the direct symlink, the other two stay in place, I can use them by calling them directly or if I need to change my default link to be one of the others it's as simple as using the config option again.  And then I installed version 2.3 and gave it a priority of 110, so it's now my new default.

Easy peasy.

No comments: