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 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
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.
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
alternatives command is not considered an appropriate solution. For those terms, because they're environment variables and should be defined in
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 (
nem) to be associated with one command:
em. To help keep the different roles of terminology clear, assume that
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
/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
$ 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
$ sudo alternatives --remove-all uemacs
This removes everything about
uemacs from the
alternatives subsystem: the symlink in
/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 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
/usr/lib/jvm/java-1.8.0-openjdk-220.127.116.11.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.