update-alternatives Command on Ubuntu and Debian

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:
update-alternatives [OPTIONS] COMMANDCommands 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:
update-alternatives --get-selectionsawk auto /usr/bin/mawk
editor auto /bin/nano
pager auto /bin/more
vi auto /usr/bin/vim.basicThe 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:
update-alternatives --list java/usr/lib/jvm/java-17-openjdk-amd64/bin/java
/usr/lib/jvm/java-21-openjdk-amd64/bin/javaThis 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:
update-alternatives --display javajava - 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.gzThe 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:
sudo update-alternatives --config javaThere 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: 1Type 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:
sudo update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/javaThe 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:
ls -l /opt/acme-tool-1.0/bin/acme-tool /opt/acme-tool-2.0/bin/acme-toolRegister both releases under the same acme-tool group:
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 200The arguments are:
--install LINK NAME PATH PRIORITYLINKis the path where the generic command link will be created (/usr/local/bin/acme-tool).NAMEis the alternative group name (acme-tool).PATHis the actual binary (/opt/acme-tool-1.0/bin/acme-tool).PRIORITYis the numeric weight used inautomode (higher wins).
In this example, automatic mode selects version 2.0 because it has the higher priority.
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:
update-alternatives --display acme-toolThen deregister the path:
sudo update-alternatives --remove acme-tool /opt/acme-tool-1.0/bin/acme-toolThe 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:
sudo update-alternatives --auto javaThe 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:
sudo update-alternatives --config editorSelect 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
| Task | Command |
|---|---|
| List all alternative groups | update-alternatives --get-selections |
| List paths in one group | update-alternatives --list NAME |
| Display group details | update-alternatives --display NAME |
| Choose interactively | sudo update-alternatives --config NAME |
| Select a path noninteractively | sudo update-alternatives --set NAME PATH |
| Return to automatic mode | sudo update-alternatives --auto NAME |
| Register a path | sudo update-alternatives --install LINK NAME PATH PRIORITY |
| Deregister a path | sudo 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 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