To answer your first question I'd like to hint you to --query:

   --query name
          Display information about the link group like --display does, but in a machine parseable way (see section QUERY FORMAT below).

Armed with this you will get the link source, e.g. in my case for java:

usr@srv % update-alternatives --query java
Name: java
Link: /usr/bin/java
[...]

So, you see my chain goes like /usr/bin/java -> /etc/alternatives/java -> ....

Unfortunately, I don't have an answer to your second question. I've been searching for a solution for this some time ago, but it seems that there is no simple workaround, yet. What you could do is writing some hack to parse the output of the --query call, maybe like this:

update-alternatives --query java | /bin/grep Link | cut -f 2 -d " "

which you could then use as input for the --install call. But since this is quite messy in my opinion I won't recommend it. Instead you might want to have a look at galternatives, a front-end to the alternatives system. Even if I don't like to use graphical stuff for such basic jobs it is quite convenient and I ended up using this tool instead of the command line tools.

EDIT

I've been curious how update-alternatives knows what's the command symlink and took a short look into the sources. Of course the alternatives system has to store the config for each group and it turns out that it's called administrative directory and written on the man page ;-)

You'll find this information in /var/lib/dpkg/alternatives (by default). The second line in each of these files defines the master link you're looking for. You may extract it like this:

usr@srv $ sed -ne 2p /var/lib/dpkg/alternatives/java
/usr/bin/java

However, this is just a workaround for those having an older version of update-alternatives.

Answer from binfalse on Stack Exchange
Top answer
1 of 4
19

To answer your first question I'd like to hint you to --query:

   --query name
          Display information about the link group like --display does, but in a machine parseable way (see section QUERY FORMAT below).

Armed with this you will get the link source, e.g. in my case for java:

usr@srv % update-alternatives --query java
Name: java
Link: /usr/bin/java
[...]

So, you see my chain goes like /usr/bin/java -> /etc/alternatives/java -> ....

Unfortunately, I don't have an answer to your second question. I've been searching for a solution for this some time ago, but it seems that there is no simple workaround, yet. What you could do is writing some hack to parse the output of the --query call, maybe like this:

update-alternatives --query java | /bin/grep Link | cut -f 2 -d " "

which you could then use as input for the --install call. But since this is quite messy in my opinion I won't recommend it. Instead you might want to have a look at galternatives, a front-end to the alternatives system. Even if I don't like to use graphical stuff for such basic jobs it is quite convenient and I ended up using this tool instead of the command line tools.

EDIT

I've been curious how update-alternatives knows what's the command symlink and took a short look into the sources. Of course the alternatives system has to store the config for each group and it turns out that it's called administrative directory and written on the man page ;-)

You'll find this information in /var/lib/dpkg/alternatives (by default). The second line in each of these files defines the master link you're looking for. You may extract it like this:

usr@srv $ sed -ne 2p /var/lib/dpkg/alternatives/java
/usr/bin/java

However, this is just a workaround for those having an older version of update-alternatives.

2 of 4
5

Simpleton question here: Isn't the <link> always going to be the same one retrieved by a simple which [program] since that is the link that the system uses to call a program by command-line?

For instance, tracing back the links for pycharm I get:

user@computer:~$ which pycharm
/usr/bin/pycharm
user@computer:~$ ll /usr/bin/pycharm
lrwxrwxrwx 1 root root 25 Mar 12  2015 /usr/bin/pycharm -> /etc/alternatives/pycharm*
user@computer:~$ ll /etc/alternatives/pycharm 
lrwxrwxrwx 1 root root 43 Mar 12  2015 /etc/alternatives/pycharm -> /opt/pycharm-community-4.0.5/bin/pycharm.sh*

And I can then use:

sudo update-alternatives --install /usr/bin/pycharm pycharm /opt/pycharm-community-4.5.0/bin/pycharm.sh 0

For my new pycharm install.

Then maybe you could construct a script to use the output of which.

๐ŸŒ
Linux Man Pages
man7.org โ€บ linux โ€บ man-pages โ€บ man1 โ€บ update-alternatives.1.html
update-alternatives(1) - Linux manual page
Instead, it is a symbolic link to a name in the alternatives directory, which in turn is a symbolic link to the actual file referenced. This is done so that the system administrator's changes can be confined within the /usr/local/etc directory: the FHS (q.v.) gives reasons why this is a Good Thing. When each package providing a file with a particular functionality is installed, changed or removed, update-alternatives is called to update information about that file in the alternatives system.
Discussions

debian - How to use the command update-alternatives --config java - Stack Overflow
If I select 3 above and run the update-alternative command I receive the same output as above, again nothing seems to have changed except that the * is now in front of the 3, though it still reads manual mode. Is there a way to confirm that what I have done is correct? ... also you can ADD ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
java - what is update-alternatives command in linux and what is the use of it? - Stack Overflow
Releases Keep up-to-date on features we add to Stack Overflow and Stack Internal. ... Find centralized, trusted content and collaborate around the technologies you use most. Learn more about Collectives ... Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... while installation of java in Linux there is some usage of update-alternatives ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Understanding update-alternatives
You're in luck. A year or so ago, I started documenting everything I learn on linux, so I don't have to go through the annoying process of re-learning it. Here are my notes on update-alternatives: install a new default browser in ubuntu: sudo update-alternatives --install /usr/bin/x-www-browser x-www-browser /opt/mozilla/vanilla/firefox/firefox 100 the incantation is: --install So, for your case, you'd want to do this: sudo update-alternatives --install /usr/bin/editor editor /usr/bin/atom 100 For your editor, you'll also want to set the $EDITOR environment variable. You can do this by editing your shell configuration, by entering: atom ~/.bashrc and add this: export EDITOR=/usr/bin/atom You can see why I took notes on update-alternatives. The incantation is kind of weird. More on reddit.com
๐ŸŒ r/linux4noobs
9
3
August 2, 2019
linux - How to add a Path to update-alternatives --config php - Stack Overflow
I'm working on a Ubuntu 16 machine: lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 16.04.6 LTS Release: 16.04 Codename: xenial My experience More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
Baeldung
baeldung.com โ€บ home โ€บ administration โ€บ the update-alternatives command in linux
The update-alternatives Command in Linux | Baeldung on Linux
July 24, 2024 - Finally, we need to reinstall micro and add the lacking manual link with slave: $ sudo update-alternatives --install /usr/bin/editor editor /usr/bin/micro 100 \ --slave /usr/share/man/man1/editor.1.gz editor.1.gz /usr/share/man/man1/micro.1.gz
๐ŸŒ
SUSE
documentation.suse.com โ€บ sles โ€บ 15-SP5 โ€บ html โ€บ SLES-all โ€บ cha-update-alternative.html
update-alternatives: managing multiple versions of commands and files | Administration Guide | SLES 15 SP5
April 6, 2026 - Follow these steps to add the additional files to your alternatives: ... > sudo update-alternatives --install \ /usr/local/bin/foo foo /usr/local/bin/foo-2 200 \ --slave /usr/local/man/man1/foo.1.gz \ foo.1.gz \ /usr/local/man/man1/foo-2.1.gz \ --slave /etc/foo.conf \ foo.conf \ /etc/foo-2.conf > sudo update-alternatives --install \ /usr/local/bin/foo foo /usr/local/bin/foo-3 300 \ --slave /usr/local/man/man1/foo.1.gz \ foo.1.gz \ /usr/local/man/man1/foo-3.1.gz \ --slave /etc/foo.conf \ foo.conf \ /etc/foo-3.conf
๐ŸŒ
Debian
wiki.debian.org โ€บ DebianAlternatives
DebianAlternatives - Debian Wiki
If you want to do this in a script use, for example, update-alternatives --set editor /usr/bin/emacs ยท Adding a new programme as an alternative is done with update-alernatives --install.
๐ŸŒ
Linux Man Pages
linux.die.net โ€บ man โ€บ 8 โ€บ update-alternatives
update-alternatives(8) - Linux man page
Specifies the alternatives directory, when this is to be different from the default. ... Specifies the administrative directory, when this is to be different from the default. --install link name path priority [--slave slink sname spath] [--initscript service]... Add a group of alternatives to the system.
๐ŸŒ
Linux Hint
linuxhint.com โ€บ update_alternatives_ubuntu
How to Use update-alternatives Command on Ubuntu โ€“ Linux Hint
A new alternatives python should be created and Python 2 interpreter should be added there as an alternative. The same way, install Python 3 interpreter /usr/bin/python3 as an alternative of the python alternatives and set it a priority of 40 with the following command: $ sudo update-alternatives --install /usr/local/bin/python python /usr/bin/python3 40
Find elsewhere
๐ŸŒ
Thomas Venturini
thomasventurini.com โ€บ articles โ€บ how-to-use-update-alternatives
How to use update-alternatives | Thomas Venturini
May 21, 2021 - Let's say you have installed VS Code Insiders (opens new window) over the standard VS Code. To start it using the terminal you would need to call code-insiders instead of code. So let's add an alternative for code. sudo update-alternatives --install $(which code) code $(which code-insiders) 1
Top answer
1 of 12
84

Assuming one has installed a JDK in /opt/java/jdk1.8.0_144 then:

  1. Install the alternative for javac

    $ sudo update-alternatives --install /usr/bin/javac javac /opt/java/jdk1.8.0_144/bin/javac 1
    
  2. Check / update the alternatives config:

    $ sudo update-alternatives --config javac
    

If there is only a single alternative for javac you will get a message saying so, otherwise select the option for the new JDK.

To check everything is setup correctly then:

$ which javac
/usr/bin/javac

$ ls -l /usr/bin/javac
lrwxrwxrwx 1 root root 23 Sep  4 17:10 /usr/bin/javac -> /etc/alternatives/javac

$ ls -l /etc/alternatives/javac
lrwxrwxrwx 1 root root 32 Sep  4 17:10 /etc/alternatives/javac -> /opt/java/jdk1.8.0_144/bin/javac

And finally

$ javac -version
javac 1.8.0_144

Repeat for java, keytool, jar, etc as needed.

2 of 12
76

You will notice a big change when selecting options if you type in "java -version" after doing so. So if you run update-alternatives --config java and select option 3, you will be using the Sun implementation.
Also, with regards to auto vs manual mode, making a selection should take it out of auto mode per this page stating:

When using the --config option, alternatives will list all of the choices for the link group of which given name is the master link. You will then be prompted for which of the choices to use for the link group. Once you make a change, the link group will no longer be in auto mode. You will need to use the --auto option in order to return to the automatic state.

And I believe auto mode is set when you install the first/only JRE/JDK.

Top answer
1 of 2
9

Basically it says to your machine to use this alternative of Jave JDK instead of the default one, which, in Linux systems, is OpenJDK.

A brief extract from the man page is better than any answer I could write:

update-alternatives creates, removes, maintains and displays information about the symbolic links comprising the Debian alternatives system.

It is possible for several programs fulfilling the same or similar functions to be installed on a single system at the same time. For example, many systems have several text editors installed at once. This gives choice to the users of a system, allowing each to use a different editor, if desired, but makes it difficult for a program to make a good choice for an editor to invoke if the user has not specified a particular preference.

Debian's alternatives system aims to solve this problem. A generic name in the filesystem is shared by all files providing interchangeable functionality. The alternatives system and the system administrator together determine which actual file is referenced by this generic name. For example, if the text editors ed(1) and nvi(1) are both installed on the system, the alternatives system will cause the generic name /usr/bin/editor to refer to /usr/bin/nvi by default. The system administrator can override this and cause it to refer to /usr/bin/ed instead, and the alternatives system will not alter this setting until explicitly requested to do so.

With --install you specified a link, "/usr/bin/java" a name "java" and a path "/usr/lib/java/JDK...." and you add a group of alternatives to the system. link is the generic name for the master link, name is the name of its symlink in the alternatives directory, and path is the alternative being introduced for the master link.

I hope to be clear enough, Here there is a post regarding java alternatives.

For the complete usage list I suggest to look at the same manual page, typing man update-alternatives on your OS shell;

2 of 2
0

i want to explain it for you from scratch ... if you have 2 or more versions of a program that starts with a same command in linux you can use update-alternatives command for determining the default version of that program and you can also change the default version of that command easily .. assume that you have 2 version of python on your system. python 2 & python 3. by default python command on linux starts the python2 interpreter on the shell . you think that python 2 is old and you want to use python 3 instead of python2 . one of the solution is that you enter python3 command on the shell and start the python interpreter that its version is more than 3 ... but you want to enter python command and shell recognize that you want to run python3 interpreter . here,update-alternatives command do it's work and determine the default version and versions of a program you want to use for a specific command .

i told you that python command start python 2 interpreter by default . you want to change it . follow the example :

sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1.

when you execute this command on linux you are telling to shell that after this time two links of two different programs are linked to python command on linux .. infact you install the python3 program on python command on linux and two programs exist at 1 command that you can change the defaults of these programs and run what of these programs you want by changing priority in command or configure it manually to set the default program ..

hope this is useful for you !

๐ŸŒ
Reddit
reddit.com โ€บ r/linux4noobs โ€บ understanding update-alternatives
r/linux4noobs on Reddit: Understanding update-alternatives
August 2, 2019 -

(tl;dr at bottom)

Apologies for sounding dumb, but I'm trying to understand Ubuntu's update-alternatives by reading the man pages and I just can't seem to understand it.

I'm trying to set atom (/usr/bin/atom) as an alternative for editor. There are two ways the man pages seem to be telling me to do it, but I get an error on both that I don't totally understand:

$ sudo update-alternatives --set editor /usr/bin/atom
update-alternatives: error: alternative /usr/bin/atom for editor not registered; not setting

There's also update-alternatives --install <link> <name> <path> <priority>, but I can't figure out what it wants for <link>. For all other alternatives it seems to just be a symlink to <path>, which is a bit strange, but I tried creating a symlink and I got an error Okay, now I'm not getting the same error, but it was something like "Max recursion reached". Now I can set the editor alternative to atom, but nothing appears to be different when I try to open a text document.

I feel like I'm just misunderstanding the arguments... could I get some help, please?

TL;DR I want to set /usr/bin/atom as the editor alternative, how do I do it

๐ŸŒ
DEV Community
dev.to โ€บ webduvet โ€บ how-to-manage-versions-using-update-alternatives-258e
How to manage versions using update-alternatives - DEV Community
November 24, 2022 - It is a tool provided by Debian based distributions which is designed to help to manage multiple versions or different implementations of a command or program, read more on Debian Alternatives. Update-alternatives in Debian based system like Ubuntu is used as default option by apt, however, it offers the command-line interface to interact with the settings and to add and remove entries manually.
๐ŸŒ
SUSE
documentation.suse.com โ€บ es-es โ€บ sles โ€บ 15-SP1 โ€บ html โ€บ SLES-all โ€บ cha-update-alternative.html
SLES 15 SP1 | Administration Guide | update-alternatives: Managing Multiple Versions of Commands and Files
Follow these steps to add the additional files to your alternatives: ... > sudo update-alternatives --install \ /usr/local/bin/foo foo /usr/local/bin/foo-2 200 \ --slave /usr/local/man/man1/foo.1.gz \ foo.1.gz \ /usr/local/man/man1/foo-2.1.gz \ --slave /etc/foo.conf \ foo.conf \ /etc/foo-2.conf > sudo update-alternatives --install \ /usr/local/bin/foo foo /usr/local/bin/foo-3 300 \ --slave /usr/local/man/man1/foo.1.gz \ foo.1.gz \ /usr/local/man/man1/foo-3.1.gz \ --slave /etc/foo.conf \ foo.conf \ /etc/foo-3.conf
๐ŸŒ
Ubuntu
manpages.ubuntu.com โ€บ trusty โ€บ man(8)
Ubuntu Manpage: update-alternatives - maintain symbolic links determining default commands
When a link group is in manual mode, the alternatives system will not make any changes to the system administrator's settings. --install link name path priority [--slave link name path]... Add a group of alternatives to the system. link is the generic name for the master link, name is the name of its symlink in the alternatives directory, and path is the alternative being introduced for the master link.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ how-to-use-update-alternatives
How to use update-alternatives - GeeksforGeeks
November 16, 2023 - To add NVim to update-alternatives when using Snap under Ubuntu, we can do this by using two different methods.
๐ŸŒ
TecAdmin
tecadmin.net โ€บ linux-update-alternatives-command
Update-alternatives Command: A Comprehensive Guide for Linux Users โ€“ TecAdmin
April 26, 2025 - For example, you have 2 versions of Java installed on your system. Thyen you can install the alternatives as: sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1100 sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-8-openjdk-amd64/bin/java 800
๐ŸŒ
Red Hat
redhat.com โ€บ en โ€บ blog โ€บ alternatives-command
Introduction to the alternatives command in Linux
November 20, 2025 - 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.
๐ŸŒ
guvi.in
studytonight.com โ€บ linux-guide โ€บ update-alternatives-command-in-linux
update-alternatives Command in Linux
February 13, 2023 - The update-alternatives command is a part of a package manager utility and it is installed with dpkg/chkconfig package: ... Let's say you have Python 2 and Python 3 installed on your PC as an example. You can create a new Python executable (/usr/local/bin/python) and add every Python version that is currently available to the alternatives database by using the update-alternatives command.