alternatives (or update-alternatives) is a GNU-licensed command-line tool that provides functionality to create, remove, manage, and query symbolic links. In other words, it allows defining default versions or paths for specific commands through symbolic links. Note that Debian-based Linux distributions only provide the update-alternatives command (the original alternatives script was reimplemented to remove perl language dependency), and there are some differences in functionality compared to RedHat-based Linux commands, but this article covers only common functionality and options. Examples are based on RedHat.
For easier understanding, I’ll use Maven installation on the system and connecting it via symbolic links. Assume Maven is installed at /usr/lib/apache-maven-*. Of course, other applications are also possible.
The --install action creates symbolic links. On RedHat, alternatives creates symbolic links in /etc/alternatives/<name> by default, and stores mode, priority, link, and path information in /var/lib/alternatives/<name>. When a symbolic link is created for the first time, a symbolic link to /etc/alternatives/<name> is created at the <link> path. (<link>->/etc/alternatives/<name>-><path>)
The --slave option is used to manage additional commands along with the master symbolic link. For example, when creating a symbolic link for the java command, you can also manage additional commands like javac, javadoc, etc. The --slave option can be defined multiple times.
1
2
3
4
5
$ alternatives --install <link> <name> <path> <priority> [--slave <link> <name> <path>]*
<link> : Enter the symbolic link path.
<name> : Enter the symbolic link group name managed by alternatives.
<path> : Enter the absolute path of the package.
<priority> : Specify priority within the link group. Enter as integer; higher is better.
# Create symbolic link for Maven 3.3.3 at /usr/local/bin/mvn$ alternatives --install /usr/local/bin/mvn mvn /usr/lib/apache-maven-3.3.3/bin/mvn 30303# Create symbolic link for Maven 3.3.9 at /usr/local/bin/mvn$ alternatives --install /usr/local/bin/mvn mvn /usr/lib/apache-maven-3.3.9/bin/mvn 30309# You can see symbolic links created at the following paths$ ll /etc/alternatives/mvn
lrwxrwxrwx 1 root root 35 Mar 18 00:34 /etc/alternatives/mvn -> /usr/lib/apache-maven-3.3.9/bin/mvn
$ ll /usr/local/bin/mvn
lrwxrwxrwx 1 root root 21 Mar 18 00:34 /usr/local/bin/mvn -> /etc/alternatives/mvn
# You can see metadata stored at the following path$ ll /var/lib/alternatives/mvn
-rw-r--r-- 1 root root 109 Mar 18 00:34 /var/lib/alternatives/mvn
$ cat /var/lib/alternatives/mvn
auto
/usr/local/bin/mvn
/usr/lib/apache-maven-3.3.3/bin/mvn
30303/usr/lib/apache-maven-3.3.9/bin/mvn
30309
Note: To change the paths where alternatives manages symbolic links and metadata, use the --altdir <directory> and --admindir <directory> command options.
The --remove action removes created symbolic links. Specifically, it removes from alternatives metadata, and if there are no connectable symbolic links within the <name> link group, both /etc/alternatives/<name> symbolic link and /var/lib/alternatives/<name> are also destroyed. If there are other alternatives, alternatives automatically updates to that link.
1
2
3
$ alternatives --remove <name> <path>
<name> : Enter the symbolic link group name managed by alternatives.
<path> : Enter the absolute path of the package to delete.
# Remove symbolic link metadata for /usr/lib/apache-maven-3.3.9/bin/mvn from mvn symbolic link group$ alternatives --remove mvn /usr/lib/apache-maven-3.3.9/bin/mvn
# case1) If apache-maven-3.3.3/bin/mvn is connected with the same group name, it updates to that path$ ll /etc/alternatives/mvn
lrwxrwxrwx 1 root root 35 Mar 18 00:49 /etc/alternatives/mvn -> /usr/lib/apache-maven-3.3.3/bin/mvn
$ ll /var/lib/alternatives/mvn
-rw-r--r-- 1 root root 67 Mar 18 00:49 /var/lib/alternatives/mvn
$ cat /var/lib/alternatives/mvn
auto
/usr/local/bin/mvn
/usr/lib/apache-maven-3.3.3/bin/mvn
30303# case2) If there are no other alternatives in the mvn symbolic link group, files and links at /etc/alternatives/mvn, /var/lib/alternatives/mvn, and /usr/local/bin/mvn are removed$ ll /etc/alternatives/mvn
ls: cannot access /etc/alternatives/mvn: No such file or directory
$ ll /var/lib/alternatives/mvn
ls: cannot access /var/lib/alternatives/mvn: No such file or directory
$ ll /usr/local/bin/mvn
ls: cannot access /usr/local/bin/mvn: No such file or directory
The --auto action sets alternatives-registered symbolic links to be automatically selected within the link group. It preferentially selects the link with the highest <priority> value, and if the automatically selected link is removed, it connects to another alternative link.
1
2
$ alternatives --auto <name>
<name> : Enter the symbolic link group name managed by alternatives.
1
2
3
4
5
6
7
8
9
10
11
12
# Set mvn registered symbolic link group to auto mode$ alternatives --auto mvn
# You can see 'auto' in the first line of metadata$ cat /var/lib/alternatives/mvn
auto
/usr/local/bin/mvn
/usr/lib/apache-maven-3.3.3/bin/mvn
30303/usr/lib/apache-maven-3.3.9/bin/mvn
30309
# Prompts user to input which command to use by default$ alternatives --config mvn
There are 2 programs which provide 'mvn'.
Selection Command
-----------------------------------------------
1 /usr/lib/apache-maven-3.3.3/bin/mvn
*+ 2 /usr/lib/apache-maven-3.3.9/bin/mvn
Enter to keep the current selection[+], or type selection number: 1# You can see the symbolic link changed and 'manual' in the first line of metadata$ ll /etc/alternatives/mvn
lrwxrwxrwx 1 root root 35 Mar 18 00:58 /etc/alternatives/mvn -> /usr/lib/apache-maven-3.3.3/bin/mvn
$ cat /var/lib/alternatives/mvn
manual
/usr/local/bin/mvn
/usr/lib/apache-maven-3.3.3/bin/mvn
30303/usr/lib/apache-maven-3.3.9/bin/mvn
30309
The --display action shows detailed information about alternatives-registered symbolic link groups. You can see command paths connected to master/slave symbolic links, current mode, currently selected link and other available links, and symbolic link priority values.
1
2
$ alternatives --display <name>
<name> : Enter the symbolic link group name managed by alternatives.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Check package information for mvn link$ alternatives --display mvn
mvn - status is manual.
link currently points to /usr/lib/apache-maven-3.3.3/bin/mvn
/usr/lib/apache-maven-3.3.9/bin/mvn - priority 30309/usr/lib/apache-maven-3.3.3/bin/mvn - priority 30303Current 'best' version is /usr/lib/apache-maven-3.3.9/bin/mvn.
# Check changed mvn mode after --auto setting$ alternatives --auto mvn
$ alternatives --display mvn
mvn - status is auto.
link currently points to /usr/lib/apache-maven-3.3.9/bin/mvn
/usr/lib/apache-maven-3.3.9/bin/mvn - priority 30309/usr/lib/apache-maven-3.3.3/bin/mvn - priority 30303Current 'best' version is /usr/lib/apache-maven-3.3.9/bin/mvn.
--list shows information about all symbolic links registered in alternatives.
1
2
$ alternatives --list
<name> : Enter the symbolic link group name managed by alternatives.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# List of all symbolic link groups registered on local machine$ alternatives --list
java_sdk_1.8.0 auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64
jre_openjdk auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre
jre_1.7.0_openjdk auto /usr/lib/jvm/jre-1.7.0-openjdk-1.7.0.131-2.6.9.0.el7_3.x86_64
java_sdk_1.8.0_openjdk auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64
java_sdk_1.7.0 auto /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131-2.6.9.0.el7_3.x86_64
mvn auto /usr/lib/maven-3.3.9/bin/mvn
java_sdk_openjdk auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64
jre_1.7.0 auto /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131-2.6.9.0.el7_3.x86_64/jre
jre_1.8.0 auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre
ld auto /usr/bin/ld.bfd
javac auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/bin/javac
java auto /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre/bin/java
libnssckbi.so.x86_64 auto /usr/lib64/pkcs11/p11-kit-trust.so
jre_1.8.0_openjdk auto /usr/lib/jvm/jre-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64
java_sdk_1.7.0_openjdk auto /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.131-2.6.9.0.el7_3.x86_64