Alternative command summary

Reprint: https://blog.csdn.net/chenxizhan1995/article/details/102990830?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control

Install Python 3 on CentOS. The default Python is python2 7.
I want python to point to python 3.6 by default, which can be modified manually.
But I thought of an alternative command that could automate the process, so I studied it again and made records.

1. Key concepts

Read the manual first.

Some software have the same or similar functions and can replace each other. For example, 1) / usr/bin/vi and / usr/bin/ed are both editors and can be used as substitutes for each other; For another example, 2) gcc 4.2 and gcc 9.2 are only different versions, and they obviously replace each other; 3) OpenJDK, Oracle JDK and their different versions can replace each other. Alternative system is used to solve these problems.
Take 1) as an example, you can set / user/bin/vi as the default editor of the whole system. One way is to create a symbolic link / usr/bin/editor to point to / usr/bin/vi by default. Other users and programs only need to call the editor command to use the editor; When the administrator wants to change the default editor, simply change the point of / user/bin/editor.
Gossip, like 1) this simple situation is also very convenient to complete manually, but a) if there are many programs, it is easy to be confused and forgotten by manual management; b) Some software contains multiple executable files at the same time, and their switching should be overall switching, which is easy to be disordered manually; c) Manual switching requires managers to have a very thorough understanding of the software, otherwise what to do if they make a mistake, such as making a mistake about the corresponding relationship between the software and the document, but if there is an alternative system, then everyone should abide by its use rules, let the software publisher be responsible for managing the relationship between various parts of the software, and then package it into the RPM distribution package, Can greatly reduce the burden on administrators.
To get back to the point, 1) in alternatives, we will implement / usr/bin/editor – > / etc/alternatives / editor – > / usr/bin/vi in this way, which is to add an additional layer of indirect symbolic links under the / etc/alternatives / directory. vi and ED are both text editors and point to one of them with / user/bin/editor. In the alternative system, we say that software vi and ED have the same generic name: editor, and call / usr/bin/editor link, and / usr/bin/vi and / usr/bin/ed path; This is the most basic situation. Software like gcc contains multiple executable programs gcc and g + +, which has the concept of master and slave links.
A generic name contains multiple alternatives. Each alternative is also called a group. A group is composed of at least one master link and zero to many slave links.
--------
Copyright notice: This is the original article of CSDN blogger "chenxizhan 1995", which follows the CC 4.0 BY-SA copyright agreement. For reprint, please attach the source link of the original text and this notice.
Original link: https://blog.csdn.net/chenxizhan1995/article/details/102990830

alternative directory: / etc/alternatives: the middle layer of symbolic links in the alternative system is saved here.

administration directory: / var/lib/alternatives: This is the database of the alternative system. All alternative are registered here and the status information of each alternative is saved.
Master-slave link is to solve the problem of software integrity: when the master link is set as default and deleted, the slave link will be processed synchronously.


Automatic mode and manual mode: after a generic name is installed for the first time, it is in automatic mode; Once a group is manually set as the default group, it becomes manual mode and remains in manual mode until it is explicitly set to automatic mode by using the command. The meaning of automatic mode is that the alternative system will automatically update relevant links when installing and uninstalling software; In manual mode, the system does not make any changes to the links, everything has the final say of the system administrator.
 

Each link group is, at any given time, in one of two modes: automatic or manual. When a group is in automatic mode, the alternatives system will automatically decide, as packages are installed and removed, whether and how to update the links. In manual mode, the alternatives system will not change the links; it will leave all the decisions to the system administrator.
Finally, each group under the same name has an associated priority, such as 0, 30 and 50. The higher the value, the higher the priority, and 50 is higher than 30; In automatic mode, the system selects the default group according to priority.
 

# 1. --install register a new group into generic name
# alternatives --install link name path priority[--slave slink sname spath]...
$ sudo alternatives --install /usr/bin/gcc gcc /usr/local/bin/gcc 4 --slave /usr/bin/g++ g++ /usr/local/bin/g++
# 2. --display name displays the groups contained in a common name, as well as the priority and master-slave links of each group
# 3. --list lists all groups in the alternative system
$ alternatives --list
$ alternatives --dispaly gcc
# 4 -- config name interactively change the default group in a common name; it's fine too
# 5. --set name path directly sets the default group (the path here is the actual path of the master link in the group)
# 6. --auto name set the mode of name to automatic
# 7. --remove name path deletes a group
# Thus, in the command line, name + path can uniquely identify a group.

2. Do an experiment

2.1 environment

$ cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
$ uname -r
3.10.0-1062.4.1.el7.x86_64
$ alternatives --version
alternatives version 1.7.4

2.2 register and execute commands

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

Among them,

  • install indicates installation
  • Link is a symbolic link
  • name is the identifier
  • Path is the path to the execution file
  • Priority indicates priority
# 1. Create a file to simulate three replaceable "programs"
mkdir -p /usr/bin/t0 &&  cd /usr/bin/t0
[root@lcs2 t0]# cat t0
#/bin/bash
echo hello, t0, $(date +%F)
[root@lcs2 t0]# cat t1
#/bin/bash
echo hello, t1, $(date +%F)
[root@lcs2 t0]# cat t2
#/bin/bash
echo hello, t2, $(date +%F)

# 2. Grant executive authority
[root@lcs2 t0]# chmod a+x t?
[root@lcs2 t0]# ll
total 12
-rwxr-xr-x 1 root root 39 2 January 20:47 t0
-rwxr-xr-x 1 root root 39 2 January 20:46 t1
-rwxr-xr-x 1 root root 39 2 January 20:46 t2

# 3. "Install" into alternatives
[root@lcs2 t0]# alternatives --install /usr/bin/t t /usr/local/t0/t0 10
[root@lcs2 t0]# alternatives --install /usr/bin/t t /usr/local/t0/t1 20
[root@lcs2 t0]# alternatives --install /usr/bin/t t /usr/local/t0/t2 30
# Execute command t
[root@lcs2 t0]# t
hello, t2, 2021-02-01

Opt: during installation, the basic name of < Path > and < name > do not have to be the same.

[root@lcs2 t0]# alternatives --install /usr/bin/t0 my-t0 /usr/local/t0/t0 0
[root@lcs2 t0]# alternatives --install /usr/bin/t0 my-t0 /usr/local/t0/t1 10
[root@lcs2 t0]# alternatives --display my-t0
my-t0 - status is auto.
 link currently points to /usr/local/t0/t1
/usr/local/t0/t0 - priority 0
/usr/local/t0/t1 - priority 10
Current `best' version is /usr/local/t0/t1.

2.3 viewing

# 4. Check what alternatives say
[root@lcs2 t0]# alternatives --display t
t - status is auto.
 link currently points to /usr/local/t0/t1
/usr/local/t0/t0 - priority 10
/usr/local/t0/t1 - priority 20
/usr/local/t0/t2 - priority 30
Current 'best' version is /usr/local/t0/t2

2.4 switching

[root@lcs2 t0]# alternatives --set t /usr/local/t0/t1
[root@lcs2 t0]# t
hello, t1, 2021-02-01
[root@lcs2 t0]# alternatives --display t
t - status is manual.
 link currently points to /usr/local/t0/t1
/usr/local/t0/t0 - priority 10
/usr/local/t0/t1 - priority 20
/usr/local/t0/t2 - priority 30
Current `best' version is /usr/local/t0/t2.

After manual setting, it becomes manual mode
When switching, if the specified is not already registered, a prompt will be given.

[root@lcs2 t0]# alternatives --set my-t0 /usr/local/t0/t2
/usr/local/t0/t2 has not been configured as an alternative for my-t0

Another way to switch is, -- config, which will enter interactive mode.

[root@lcs2 t0]# alternatives --display t
t - status is auto.
 link currently points to /usr/local/t0/t2
/usr/local/t0/t0 - priority 10
/usr/local/t0/t1 - priority 20
/usr/local/t0/t2 - priority 30
Current 'best' version is /usr/local/t0/t2.
[root@lcs2 t0]# alternatives --config t

There are 3 programs which provide 't'.

  Selection    Command
-----------------------------------------------
   1           /usr/local/t0/t0
   2           /usr/local/t0/t1
*+ 3           /usr/local/t0/t2

Enter to keep the current selection[+], or type selection number: 2
[root@lcs2 t0]# alternatives --display t
t - status is manual.
 link currently points to /usr/local/t0/t1
/usr/local/t0/t0 - priority 10
/usr/local/t0/t1 - priority 20
/usr/local/t0/t2 - priority 30
Current 'best' version is /usr/local/t0/t2.

2.5 deletion

# 1. Delete and view
[root@lcs2 t0]# alternatives --remove t /usr/local/t0/t2
[root@lcs2 t0]# alternatives --display t
t - status is manual.
 link currently points to /usr/local/t0/t1
/usr/local/t0/t0 - priority 10
/usr/local/t0/t1 - priority 20
Current 'best' version is /usr/local/t0/t1.

# 2. If you delete the currently effective order,
[root@lcs2 t0]# alternatives --remove t /usr/local/t0/t1
# Automatically selects from the remaining commands and switches to automatic mode.
[root@lcs2 t0]# alternatives --display t
t - status is auto.
 link currently points to /usr/local/t0/t0
/usr/local/t0/t0 - priority 10
Current 'best' version is /usr/local/t0/t0.

# 3. If the path is incorrect during deletion, you will be prompted
# alternatives --remove t /usr/bin/local/t0/t0
/usr/bin/local/t0/t0 has not been configured as an alternative for t

3. Further experiments

What happens when switching?
alternatives realizes the switching between different specific commands of similar commands through symbolic links.

# 1. It is currently in automatic mode, and use t to finally point to t2
[root@lcs2 t0]# t
hello, t2, 2021-02-01
[root@lcs2 t0]# alternatives --display t
t - status is auto.
 link currently points to /usr/local/t0/t2
/usr/local/t0/t0 - priority 10
/usr/local/t0/t1 - priority 20
/usr/local/t0/t2 - priority 30
Current 'best' version is /usr/local/t0/t2.

# 2. Follow the path to check
[root@lcs2 t0]# ll $(which t)
lrwxrwxrwx 1 root root 19 2 January 21:29 /bin/t -> /etc/alternatives/t
[root@lcs2 t0]# ll /etc/alternatives/t
lrwxrwxrwx 1 root root 16 2 January 21:29 /etc/alternatives/t -> /usr/local/t0/t2

The link points to: / bin / T - > / etc / alternatives / T - > / usr / local / t0 / T2

Make a switch and observe the link:

# 1. Setting
[root@lcs2 t0]# alternatives --set t /usr/local/t0/t0
[root@lcs2 t0]# t
hello, t0, 2021-02-01
[root@lcs2 t0]# alternatives --display t
t - status is manual.
 link currently points to /usr/local/t0/t0
/usr/local/t0/t0 - priority 10
/usr/local/t0/t1 - priority 20
/usr/local/t0/t2 - priority 30
Current 'best' version is /usr/local/t0/t2.
# 2. Follow the path to view
[root@lcs2 t0]#  ll $(which t)
lrwxrwxrwx 1 root root 19 2 January 21:35 /bin/t -> /etc/alternatives/t
[root@lcs2 t0]#  ll /etc/alternatives/t
lrwxrwxrwx 1 root root 16 2 January 21:35 /etc/alternatives/t -> /usr/local/t0/t0

The link points to: / bin / T - > / etc / alternatives / T - > / usr / local / t0 / t0.

It can be considered that the link to the / etc/alternatives directory is fixed, and the change is / etc/alternatives
The point of the link in.

4. master and slave experiments

4.1 create several files to simulate the master slave command

[root@lcs2 ms]# ls
m1  s1a  s1b  s1c
[root@lcs2 ms]# cat *
#!/bin/bash
echo master-1
#!/bin/bash
echo slave-1-a
#!/bin/bash
echo slave-1-b
#!/bin/bash
echo slave-1-c

[root@lcs2 ms]# ./m1
master-1
[root@lcs2 ms]# ./s1a
slave-1-a
[root@lcs2 ms]# ./s1b
slave-1-b
[root@lcs2 ms]# ./s1c
slave-1-c
[root@lcs2 ms]# ./m2
master-2
[root@lcs2 ms]# ./s2a
slave-2-a
[root@lcs2 ms]# ./s2b
slave-2-b
[root@lcs2 ms]# ./s2c
slave-2-c

4.2 registration, switching and execution (to be continued)

# 1. Registration
[root@lcs2 ms]# alternatives --install /usr/bin/m m /usr/local/ms/m1 10 \
    --slave /usr/bin/sa sa /usr/local/ms/s1a \
    --slave /usr/bin/sb sb /usr/local/ms/s1b \
    --slave /usr/bin/sc sc /usr/local/ms/s1c
[root@lcs2 ms]# alternatives --install /usr/bin/m m /usr/local/ms/m2 20 \
    --slave /usr/bin/sa sa /usr/local/ms/s2a \
    --slave /usr/bin/sb sb /usr/local/ms/s2b \
    --slave /usr/bin/sc sc /usr/local/ms/s2c

# 2. View
[root@lcs2 ms]# alternatives --display m
m - status is auto.
 link currently points to /usr/local/ms/m2
/usr/local/ms/m1 - priority 10
 slave sa: /usr/local/ms/s1a
 slave sb: /usr/local/ms/s1b
 slave sc: /usr/local/ms/s1c
/usr/local/ms/m2 - priority 20
 slave sa: /usr/local/ms/s2a
 slave sb: /usr/local/ms/s2b
 slave sc: /usr/local/ms/s2c
Current 'best' version is /usr/local/ms/m2.
# 3. Call / execute command
[root@lcs2 ms]# m
master-2
[root@lcs2 ms]# sa
slave-2-a
[root@lcs2 ms]# sb
slave-2-b
[root@lcs2 ms]# sc

# 4. Switching
[root@lcs2 ms]# alternatives --set m /usr/local/ms/m1
# 5. Check and switch from command to command
[root@lcs2 ms]# alternatives --display m
m - status is manual.
 link currently points to /usr/local/ms/m1
/usr/local/ms/m1 - priority 10
 slave sa: /usr/local/ms/s1a
 slave sb: /usr/local/ms/s1b
 slave sc: /usr/local/ms/s1c
/usr/local/ms/m2 - priority 20
 slave sa: /usr/local/ms/s2a
 slave sb: /usr/local/ms/s2b
 slave sc: /usr/local/ms/s2c
Current 'best' version is /usr/local/ms/m2.
# 6. Call. The switch is indeed effective
[root@lcs2 ms]# m
master-1
[root@lcs2 ms]# sa
slave-1-a
[root@lcs2 ms]# sb
slave-1-b
[root@lcs2 ms]# sc
slave-1-c

# delete
alternatives --remove m /usr/local/ms/m1
alternatives --remove m /usr/local/ms/m2

5. Attachment: alternatives and java

# Current java version
$ java -version
openjdk version "1.8.0_232"
OpenJDK Runtime Environment (build 1.8.0_232-b09)
OpenJDK 64-Bit Server VM (build 25.232-b09, mixed mode)
# java is indeed under the control of the alternatives command
$ alternatives --list  | grep java
servlet auto    /usr/share/java/tomcat-servlet-3.0-api.jar
java    auto    /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/jre/bin/java
jre_openjdk     auto    /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/jre
jre_1.8.0       auto    /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/jre
jaxp_transform_impl     auto    /usr/share/java/xalan-j2.jar
jaxp_parser_impl        auto    /usr/share/java/xerces-j2.jar
javac   auto    /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/bin/javac
java_sdk_openjdk        auto    /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64
java_sdk_1.8.0  auto    /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64
java_sdk_1.8.0_openjdk  auto    /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64
# Each time you execute a java command, it corresponds to this
$ which java
/usr/bin/java
# The actual path is
$ realpath /usr/bin/java
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/jre/bin/java
# /usr/bin/java is a symbolic link to a file with the same name in the / etc/alternatives / directory
$ ll /usr/bin/java
lrwxrwxrwx 1 root root 22 10 July 26:38 /usr/bin/java -> /etc/alternatives/java
#  /etc/alternatives/java is also a symbolic link that points to a real java file
$ ll /etc/alternatives/java
lrwxrwxrwx 1 root root 73 10 July 26:38 /etc/alternatives/java -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.232.b09-0.el7_7.x86_64/jre/bin/java
$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/

It can be seen that the alternatives command uses the most basic things: PATH path + symbolic link. We can implement these operations purely by hand, but alternatives automate these steps and make them convenient.
There are some small problems,

  1. Switching the jdk version is not only as simple as switching a java command, but also a series of related commands such as javac, javah, javap, etc. How to deal with them
  2. gcc is not only a gcc command, but also a corresponding header file

6. misc
appointment
A good auxiliary tool must cooperate with the usage agreement agreed by everyone in order to achieve the expected effect of the tool.
In addition to the administrator's manual management and switching between similar software, alternatives are generally called by the% pre or% post procedure of the rpm installation package to add the software to a software group, especially the software installed and uninstalled by the package management system (apt, yum).

Update alternatives on Ubuntu

On Ubuntu, the equivalent command is "update alternatives".
alternatives manage software, which not only includes executable programs, but also related documents (specifically man manuals), header files, library files, etc.

Q. Why add a link to / etc/alternatives?
Q. Why add an additional layer of indirect symbolic links in the / etc/alternatives directory when managing different alternatives?
The man man man page has a simple description. It is said that the advantage is that all configuration files are in the / etc / directory. For detailed advantages, refer to FHS.
The generic name is not a direct symbolic link to the selected alternative. 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 administra tor's changes can be confined within the /etc directory: the FHS (q.v.) gives reasons why this is a Good Thing.
 

Q. According to the truth, openjdk and Oracle should use the same common name, but the actual situation is not java, jre, openjdk, messy.

ref

Use the Linux alternatives command to replace the version of the selected software

Keywords: Java Linux

Added by Hitch54 on Mon, 17 Jan 2022 13:42:56 +0200