27

I've looked up the manual of update-alternatives several times but I can't find out how to show the current link pointing to a specific alternative, and that information is needed when adding a new alternative.

From the update-alternatives manual:

--install <link> <name> <path> <priority>

Let's say I want to add a new version of Java Runtime Edition, but I don't know the current symlink that links to the alternative (<link> parameter). What I currently do is:

sudo update-alternatives --install /tmp/randomStuff java /usr/local/java/jre1.7.0_25/bin/java 0

That command will output:

update-alternatives: renaming java link from /usr/local/bin/java to /tmp/randomStuff.

Reading the output I find out the old link that was pointing to the alternative, so I can finally run my command again with the right <link> parameter, changing /tmp/randomStuff to /usr/local/bin/java:

sudo update-alternatives --install /usr/local/bin/java java /usr/local/java/jre1.7.0_25/bin/java 0

That works fine, but as you see, running the command with /tmp/randomStuff as the <link> parameter is very awkward.

So, here comes the questions: (1) Are there any update-alternative arguments that can output the current link that is pointing to a specific alternative, or (2) is there a way to install a new alternative without having to provide a new parameter, simply keeping the current <link>?

3 Answers 3

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.

4
  • Thanks for answering, but the version of update-alternatives that I'm running (1.16.1.2) does not show link information using neither --query or --display. What version are you using? sudo update-alternatives --query java Link: java Status: auto Best: /usr/local/java/jre1.6.0_45/bin/java Value: /usr/local/java/jre1.6.0_45/bin/java Alternative: /usr/local/java/jre1.6.0_45/bin/java Priority: 0
    – pagliuca
    Jul 7, 2013 at 5:00
  • I've 1.16.10 installed. Can't you update your version?
    – binfalse
    Jul 7, 2013 at 8:51
  • You are the man! Both solutions are excellent!
    – pagliuca
    Jul 7, 2013 at 17:32
  • That's the way. Thank you very much!
    – Smeterlink
    Jan 17, 2021 at 15:08
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.

1
  • Thanks for the tip, but there are times when that will not be helpful. I use update-alternatives to also keep track of java and flash plugins for firefox, and I always forget the path "/usr/lib/mozilla/plugins" where I should put those plugins. I can't find out that path using which or whereisor any command that comes to my mind, whereas the answer from @binfalse correctly returns that path on my machine when I run update-alternatives --query java-plugin.
    – pagliuca
    Mar 8, 2016 at 14:20
1

You don't need to resupply all the existing alternatives when using --install. See the example at https://wiki.debian.org/DebianAlternatives. Here I'm adding /usr/local/bin/alacritty as an alternative for x-terminal-emulator, and selecting it:

[schwarzgerat](0) $ sudo update-alternatives --install /usr/bin/x-terminal-emualtor x-terminal-emulator /usr/local/bin/alacritty 10
update-alternatives: renaming x-terminal-emulator link from /usr/bin/x-terminal-emulator to /usr/bin/x-terminal-emualtor
[schwarzgerat](0) $ sudo update-alternatives --config x-terminal-emulator
There are 16 choices for the alternative x-terminal-emulator (providing /usr/bin/x-terminal-emualtor).

  Selection    Path                             Priority   Status
------------------------------------------------------------
  0            /usr/bin/terminator               50        auto mode
  1            /usr/bin/gnome-terminal.wrapper   40        manual mode
* 2            /usr/bin/kitty                    20        manual mode
  3            /usr/bin/koi8rxterm               20        manual mode
  4            /usr/bin/konsole                  40        manual mode
  5            /usr/bin/lxterm                   30        manual mode
  6            /usr/bin/mlterm                   20        manual mode
  7            /usr/bin/pangoterm                15        manual mode
  8            /usr/bin/st                       15        manual mode
  9            /usr/bin/terminator               50        manual mode
  10           /usr/bin/terminology              40        manual mode
  11           /usr/bin/terminus                 20        manual mode
  12           /usr/bin/urxvt                    20        manual mode
  13           /usr/bin/uxterm                   20        manual mode
  14           /usr/bin/xfce4-terminal.wrapper   40        manual mode
  15           /usr/bin/xterm                    20        manual mode
  16           /usr/local/bin/alacritty          10        manual mode

Press <enter> to keep the current choice[*], or type selection number: 16
update-alternatives: using /usr/local/bin/alacritty to provide /usr/bin/x-terminal-emualtor (x-terminal-emulator) in manual mode
[schwarzgerat](0) $

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .