update-alternatives Command on Ubuntu and Debian

By 

Published on

6 min read

Program paths converging through an update-alternatives selector to one default command

When several installed programs provide the same command, you need a reliable way to choose which one runs by default. Hard-coding paths in scripts or rebuilding symbolic links by hand makes that choice difficult to maintain.

On Ubuntu, Debian, and their derivatives, the update-alternatives command manages these selections through symbolic links in /etc/alternatives. This guide explains how to inspect alternative groups, switch programs interactively or from a script, register new choices, and return a group to automatic mode.

How It Works

update-alternatives maintains link groups. Each group has a generic command name and one or more registered program paths. For example, the java group controls which installed Java runtime /usr/bin/java starts.

The generic command is not linked directly to the selected program. Instead, /usr/bin/java points to /etc/alternatives/java, which points to the active Java binary. You can read our symbolic links guide for more about this two-step link structure.

Each group operates in one of two modes:

  • Automatic mode selects the registered alternative with the highest priority.
  • Manual mode keeps the administrator’s selection until it is changed explicitly or becomes invalid.

The command stores its administrative state under /var/lib/dpkg/alternatives.

Syntax

The general command syntax is:

txt
update-alternatives [OPTIONS] COMMAND

Commands that change an alternative group require sudo. Listing and displaying alternatives does not.

List Alternative Groups

To see every master alternative group registered on the system, run:

Terminal
update-alternatives --get-selections
output
awk                            auto     /usr/bin/mawk
editor                         auto     /bin/nano
pager                          auto     /bin/more
vi                             auto     /usr/bin/vim.basic

The second column shows whether the group is in auto or manual mode. The final column contains the selected program path. Your groups and paths will differ according to the packages installed on your system.

To list only the registered paths for one group, pass its name to --list:

Terminal
update-alternatives --list java
output
/usr/lib/jvm/java-17-openjdk-amd64/bin/java
/usr/lib/jvm/java-21-openjdk-amd64/bin/java

This example has Java 17 and Java 21 registered. If the named group does not exist, the command reports that no alternatives are registered for it.

Display an Alternative

To see all registered options for a specific alternative and which one is currently active:

Terminal
update-alternatives --display java
output
java - auto mode
  link best version is /usr/lib/jvm/java-21-openjdk-amd64/bin/java
  link currently points to /usr/lib/jvm/java-21-openjdk-amd64/bin/java
  link java is /usr/bin/java
  slave java.1.gz is /usr/share/man/man1/java.1.gz
/usr/lib/jvm/java-17-openjdk-amd64/bin/java - priority 1711
  slave java.1.gz: /usr/lib/jvm/java-17-openjdk-amd64/man/man1/java.1.gz
/usr/lib/jvm/java-21-openjdk-amd64/bin/java - priority 2111
  slave java.1.gz: /usr/lib/jvm/java-21-openjdk-amd64/man/man1/java.1.gz

The output lists each registered path with its priority. In auto mode, the highest priority wins. The slave lines show related files that follow the same selection, in this case the java manual page.

Switch Between Alternatives

To choose interactively from the registered options, run:

Terminal
sudo update-alternatives --config java
output
There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                          Priority   Status
------------------------------------------------------------
* 0            /usr/lib/jvm/java-21-openjdk-amd64/bin/java   2111      auto mode
  1            /usr/lib/jvm/java-17-openjdk-amd64/bin/java   1711      manual mode
  2            /usr/lib/jvm/java-21-openjdk-amd64/bin/java   2111      manual mode

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

Type the number of a manual choice and press Enter to pin that version. Selecting 0 keeps or restores automatic mode, while pressing Enter without a number keeps the current choice.

When a group is in manual mode, a package installation can register another choice but will not replace your valid selection.

Set an Alternative Noninteractively

The --set command changes an alternative without displaying a menu, which makes it useful in provisioning scripts. Use --list as shown above to copy the exact path, then pass it to --set:

Terminal
sudo update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java

The selected group enters manual mode. The path must already be registered in that group.

Alternative groups are independent unless their provider registered related files as slave links. For example, switching the java group does not necessarily switch javac. Use --display to check which links belong to a group.

Register a New Alternative

When you install a program outside the package manager, you can register it with --install. Assume two releases of a program are installed at /opt/acme-tool-1.0/bin/acme-tool and /opt/acme-tool-2.0/bin/acme-tool. Confirm that both executable paths exist before registering them:

Terminal
ls -l /opt/acme-tool-1.0/bin/acme-tool /opt/acme-tool-2.0/bin/acme-tool

Register both releases under the same acme-tool group:

Terminal
sudo update-alternatives --install /usr/local/bin/acme-tool acme-tool /opt/acme-tool-1.0/bin/acme-tool 100
sudo update-alternatives --install /usr/local/bin/acme-tool acme-tool /opt/acme-tool-2.0/bin/acme-tool 200

The arguments are:

txt
--install LINK NAME PATH PRIORITY
  • LINK is the path where the generic command link will be created (/usr/local/bin/acme-tool).
  • NAME is the alternative group name (acme-tool).
  • PATH is the actual binary (/opt/acme-tool-1.0/bin/acme-tool).
  • PRIORITY is the numeric weight used in auto mode (higher wins).

In this example, automatic mode selects version 2.0 because it has the higher priority.

Warning
Do not use update-alternatives to replace /usr/bin/python3 on Ubuntu or Debian. System tools depend on the distribution’s default Python interpreter. Use versioned commands, virtual environments, pyenv, or a separate command under /usr/local/bin instead.

Remove an Alternative

Before removing a registered path, display the group and confirm the exact path:

Terminal
update-alternatives --display acme-tool

Then deregister the path:

Terminal
sudo update-alternatives --remove acme-tool /opt/acme-tool-1.0/bin/acme-tool

The command removes the path from the alternatives database but does not delete the program itself. If you remove the active path, the group returns to automatic mode and selects the best remaining alternative.

Reset to Auto Mode

If you manually pinned an alternative and want to go back to automatic selection by priority:

Terminal
sudo update-alternatives --auto java

The system returns to the highest-priority option.

Switch the Editor Alternative

The editor alternative provides the system-wide /usr/bin/editor command. Programs that invoke this path follow the selected alternative, while tools such as sensible-editor may honor user-specific settings and environment variables first. To switch the system editor choice:

Terminal
sudo update-alternatives --config editor

Select an installed editor such as vim.basic from the list. Applications with their own editor setting do not necessarily follow this choice. Git, for example, checks GIT_EDITOR, core.editor, VISUAL, and EDITOR before using its compiled default.

Quick Reference

TaskCommand
List all alternative groupsupdate-alternatives --get-selections
List paths in one groupupdate-alternatives --list NAME
Display group detailsupdate-alternatives --display NAME
Choose interactivelysudo update-alternatives --config NAME
Select a path noninteractivelysudo update-alternatives --set NAME PATH
Return to automatic modesudo update-alternatives --auto NAME
Register a pathsudo update-alternatives --install LINK NAME PATH PRIORITY
Deregister a pathsudo update-alternatives --remove NAME PATH

Troubleshooting

no alternatives for NAME The group is not registered. Check the available names with update-alternatives --get-selections. Install a package that provides the group or register an existing executable with --install.

alternative path ... does not exist The path passed to --install must already exist. Check it with ls -l PATH, then correct the path or install the program before trying again.

A regular file blocks the alternatives link Do not immediately add --force. Check which package owns the path with dpkg -S /path/to/command, and back up locally installed files before replacing them with an alternatives-managed link.

Conclusion

Use --config for interactive changes, --set for scripts, and --auto when you want priority-based selection again. For a practical example with multiple JDKs, see How to Check Java Version .

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page