Skip to main content

Introduction to the alternatives command in Linux

Discover alternatives, which creates, removes, maintains, and displays information about the symbolic links comprising the alternatives system.
Image
Introduction to the alternatives command

Photo by Rodolfo Clix from Pexels

Abstractions can be helpful to users because many users don't care how their computer achieves a task as long as it's on target. In fact, even applications don't always care how something is achieved as long as all of its system calls are answered correctly. In theory, a Linux sysadmin can offer many system tools according to function rather than by the exact name of the executable, but that often requires a lot of symlinking and version tracking. Unless that is, you use the alternatives command.

The alternatives command began its life as, interestingly, an alternative. Originally, this was a convenience utility, written in Perl, from the Debian Linux project, called update-alternatives. Red Hat rewrote the command without Perl, and it's been propagated throughout Fedora-based distributions such as Red Hat and CentOS, as well as other distributions that look to Red Hat for the functional definition of the Linux Standard Base (LSB).

When to use the alternatives command

A simple and realistic example: you have a command on your system called em, which launches a simple text editor. It's been the go-to editor for your userbase for years, many people have based workflows around it and some maintain highly customized configs for it. However, your userbase has made it clear to you recently that they can't survive any longer without emoji support in their terminal editors and em doesn't support Unicode.

You find a Unicode-enabled fork of em called nem, but you know that 99% of your users are used to em, have scripts that call em, and will continue to think of any replacement application as em no matter what you do. The easy solution to this situation, and many other examples similar to it, is to designate the new nem binary as the preferred alternative to the em binary when the em command is used.

Manually creating a symlink might seem tempting, but that's not resistant to updates from a package manager, nor is it centralized.

The alternatives command is most useful when managing "generic" application names. Of course in the UNIX world, "generic" isn't always generic any more than "Kleenex" or "Xerox" is in the real world, so terms like java, (x)emacs(-nox), (n)vi(m), whois, and iptables are often some of the first to have alternatives defined for them. For truly generic terms, like EDITOR and CC, the alternatives command is not considered an appropriate solution. For those terms, because they're environment variables and should be defined in /etc or $HOME/.profile.

Creating a new alternative

Continuing with the example scenario of an old binary called em being supplanted by the new variant nem, it's easy to create an alternative entry. In this example, you must rename the original command, although in other instances this isn't necessary because the command isn't exactly what people think it is in the first place (java, for example, is rarely located in /usr/bin directly). If you do need to change the name of a binary, the right way to do that is in its RPM spec file, such that the RPM installing the command provides the binary under the new name.

In a pinch, especially if you're phasing the command out anyway, you could remove the command from the system's package management and just keep a custom version of the old command available /opt or similar.

For this example, assume you've renamed the original editor em2 (denoting its latest version number).

Now you have two binaries (em2 and nem) to be associated with one command: em. To help keep the different roles of terminology clear, assume that em and nem are both micro Emacs-style editors. In that case, a very generic term for the alternative being created might be µemacs(using the µ symbol to mean "micro") or uemacs for simplicity.

Create an alternative for the original by providing:

  • a location for the "generic" symlink
  • a name for the alternative (I've decided upon uemacs, to make it clear that it's a reference name rather than a specific binary)
  • the binary to be executed when these symlinks are called
  • a priority level to indicate which alternative is preferred
$ sudo alternatives --install /usr/bin/em uemacs /opt/em-legacy/em2 1

Create an alternative for the new binary, with a high priority because it's your preferred binary:

$ sudo alternatives --install /usr/bin/em uemacs /usr/local/bin/nem 99

These commands create a new symlink, /usr/bin/em, pointing to /etc/alternatives/em, which you can in turn point to either /opt/em-legacy/em2 or /usr/local/bin/nem. The human-friendly reference to this bundle of alternatives is uemacs, which has been arbitrarily chosen by the systems administrator because it's descriptive and memorable. You can choose the destination of the alternative symlink using the --config option:

$ sudo alternatives --config uemacs
[sudo] password for seth: 

There are 2 programs which provide 'uemacs'.

  Selection    Command
-----------------------------------------------
*+ 1           /usr/local/bin/nem
   2           /opt/em-legacy/em2

Removing an alternative

Sometimes alternatives are long-term solutions, and other times they're just to help users or admins to transition to something new. If you need to remove an alternative for any reason, you can do that with the --remove-all option, followed by the "generic" name of the alternative. In this example, that's uemacs:

$ sudo alternatives --remove-all uemacs

This removes everything about uemacs from the alternatives subsystem: the symlink in /usr/bin and /etc/alternatives. If you only want to remove one choice from an alternative, then use the --remove option, providing the alternative name (uemacs in this example) and the path of the choice you want to drop:

$ sudo alternatives --remove uemacs /opt/em-legacy/em2

Alternatives

The alternatives command has many more features, including the ability to symlink dependent components when a specific alternative is chosen. In addition to handling a lot of the heavy lifting, alternatives keeps your inconsistencies centralized. You can check in on what alternatives are in place, so you don't have to remember from day to day that emacs is actually emacs-26.3, or that java isn't java-1.8 but /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0, and so on:

$ alternatives --list

Linux is all about choice and flexibility, and the alternatives command is an example of how both users and admins can benefit from some clever sleight-of-hand.

Want to try out Red Hat Enterprise Linux? Download it now for free.

Topics:   Linux  
Author’s photo

Seth Kenlon

Seth Kenlon is a UNIX geek and free software enthusiast. More about me

Try Red Hat Enterprise Linux

Download it at no charge from the Red Hat Developer program.