在Linux系統中提供了一個alternatives命令,用於在多個同功能的軟體,或軟體的多個不同版本間選擇、切換。簡單來說就是版本切換控制。例如,你的操作系統有多個Python版本,例如python3.6,Python 3.9,如果不用alternatives命令,那麼你可能需要通過手工修改軟鏈接 ...
在Linux系統中提供了一個alternatives命令,用於在多個同功能的軟體,或軟體的多個不同版本間選擇、切換。簡單來說就是版本切換控制。例如,你的操作系統有多個Python版本,例如python3.6,Python 3.9,如果不用alternatives命令,那麼你可能需要通過手工修改軟鏈接來實現Python版本的切換。如果用alternatives命令就可以很容易的實現Python版本的切換和管理。
另外,關於命令alternatives與update-alternatives的關係,其實先有update-alternatives命令,然後才有alternatives,update-alternatives最開始是Debian Linux下的一個項目,用於管理多版本,它是Perl編寫的,然後RHEL重寫了這個項目,名字也改為了alternatives,alternatives則在基於Fedora的分發版本(Redhat, CentOS)中發行,傳播,而update-alternatives一般存在Debian Linux下。但是為了統一或者方便,在RHEL下你也會看到update-alternatives這個命令,它此時實際上是一個軟鏈接,指向alternatives命令。如下所示:
# more /etc/redhat-release
Red Hat Enterprise Linux release 8.8 (Ootpa)
# whereis alternatives
alternatives: /usr/sbin/alternatives /etc/alternatives /usr/share/man/man8/alternatives.8.gz
# whereis update-alternatives
update-alternatives: /usr/sbin/update-alternatives /usr/share/man/man8/update-alternatives.8.gz
# ll /usr/sbin/update-alternatives
lrwxrwxrwx. 1 root root 12 Jul 27 2021 /usr/sbin/update-alternatives -> alternatives
查看alternatives命令的幫助信息
alternatives或alternatives --help
$ alternatives
alternatives version 1.19.1 - Copyright (C) 2001 Red Hat, Inc.
This may be freely redistributed under the terms of the GNU Public License.
usage: alternatives --install <link> <name> <path> <priority>
[--initscript <service>]
[--family <family>]
[--slave <slave_link> <slave_name> <slave_path>]*
alternatives --remove <name> <path>
alternatives --auto <name>
alternatives --config <name>
alternatives --display <name>
alternatives --set <name> <path>
alternatives --list
alternatives --remove-all <name>
alternatives --add-slave <name> <path> <slave_link> <slave_name> <slave_path>
alternatives --remove-slave <name> <path> <slave_name>
common options: --verbose --test --help --usage --version --keep-missing --keep-foreign
--altdir <directory> --admindir <directory>
主要常使用的參數是 install ,remove,config,display,list這5個參數。
install --生成軟連接
remove --刪除軟連接
config --選擇軟連接
display --顯示軟連接
list --顯示所有軟連接
例子:顯示所有軟連接
$ alternatives --list
libnssckbi.so.x86_64 auto /usr/lib64/pkcs11/p11-kit-trust.so
python auto /usr/libexec/no-python
cifs-idmap-plugin auto /usr/lib64/cifs-utils/cifs_idmap_sss.so
ld auto /usr/bin/ld.bfd
modules.sh auto /usr/share/Modules/init/profile.sh
python3 manual /usr/bin/python3.9
例子:顯示python3的軟連接
$ alternatives --display python3
python3 - status is manual.
link currently points to /usr/bin/python3.9
/usr/bin/python3.6 - priority 1000000
slave easy_install-3: /usr/bin/easy_install-3.6
slave pip-3: /usr/bin/pip-3.6
slave pip3: /usr/bin/pip3.6
slave pydoc-3: /usr/bin/pydoc3.6
slave pydoc3: /usr/bin/pydoc3.6
slave pyvenv-3: /usr/bin/pyvenv-3.6
slave python3-man: /usr/share/man/man1/python3.6.1.gz
/usr/bin/python3.9 - priority 3900
slave easy_install-3: /usr/bin/easy_install-3.9
slave pip-3: /usr/bin/pip-3.9
slave pip3: /usr/bin/pip3.9
slave pydoc-3: /usr/bin/pydoc3.9
slave pydoc3: /usr/bin/pydoc3.9
slave pyvenv-3: (null)
slave python3-man: /usr/share/man/man1/python3.9.1.gz
Current `best' version is /usr/bin/python3.6.
如上所示,--display顯示鏈接組的所有信息,包括鏈接的模式(自動還是手動)、鏈接priority值、所有可用的鏈接命令
例子:選擇軟連接
註意,選擇軟鏈接必須使用root許可權,否則會遇到許可權問題,如下所示:
$ alternatives --config python3
There are 2 programs which provide 'python3'.
Selection Command
-----------------------------------------------
* 1 /usr/bin/python3.6
+ 2 /usr/bin/python3.9
Enter to keep the current selection[+], or type selection number: 1
failed to create /var/lib/alternatives/python3.new: Permission denied
root用戶下操作:
# alternatives --config python3
There are 2 programs which provide 'python3'.
Selection Command
-----------------------------------------------
* 1 /usr/bin/python3.6
+ 2 /usr/bin/python3.9
Enter to keep the current selection[+], or type selection number: 1
# alternatives --list
libnssckbi.so.x86_64 auto /usr/lib64/pkcs11/p11-kit-trust.so
python auto /usr/libexec/no-python
cifs-idmap-plugin auto /usr/lib64/cifs-utils/cifs_idmap_sss.so
ld auto /usr/bin/ld.bfd
modules.sh auto /usr/share/Modules/init/profile.sh
python3 manual /usr/bin/python3.6
(*)星號表示當前系統使用的版本,加號表示優先順序最高的。輸入數值可修改預設配置,直接按回車保持原來狀態
例子:生成軟連接python
alternatives --install <link> <name> <path> <priority>
# link是在/usr/bin/,/usr/local/bin/等預設PATH搜索目錄
# name是在/etc/alternatives目錄中的鏈接名
# path是真正的可執行程式的位置,可以在任何位置
# priority是優先順序
例如,當前環境只有python3,你想使用python這個命令,而不想使用python3的話,那麼我們可以生成一個軟連接。
# alternatives --install /usr/bin/unversioned-python python /usr/bin/python3.9 2
# alternatives --list | grep python
python auto /usr/bin/python3
python3 manual /usr/bin/python3.9
註意,link的命令最好合乎規範,否則可能有告警信息:
# alternatives --install /usr/bin/python python /usr/bin/python3.9 2
the primary link for python must be /usr/bin/unversioned-python
# alternatives --list
libnssckbi.so.x86_64 auto /usr/lib64/pkcs11/p11-kit-trust.so
python auto /usr/bin/python3
cifs-idmap-plugin auto /usr/lib64/cifs-utils/cifs_idmap_sss.so
ld auto /usr/bin/ld.bfd
modules.sh auto /usr/share/Modules/init/profile.sh
python3 manual /usr/bin/python3.9
關於priority優先順序, 當命令鏈接已存在時,需高於當前值,因為當alternative為自動模式時,系統預設啟用priority高的鏈接
例子:刪除軟連接
# alternatives --remove python /usr/libexec/no-python
那麼我們接下來簡單探究一下,在版本切換時,alternatvies命令做了一下啥
# alternatives --list | grep python3
python auto /usr/bin/python3
python3 manual /usr/bin/python3.9
# whereis python3
python3: /usr/bin/python3.6 /usr/bin/python3.6m /usr/bin/python3 /usr/bin/python3.9 /usr/lib/python3.6 /usr/lib/python3.9 /usr/lib64/python3.6 /usr/lib64/python3.9 /usr/include/python3.6m /usr/include/python3.9 /usr/share/man/man1/python3.1.gz
# ll /usr/bin/python3
lrwxrwxrwx. 1 root root 25 May 12 11:04 /usr/bin/python3 -> /etc/alternatives/python3
# ll /etc/alternatives/python3
lrwxrwxrwx 1 root root 18 Jul 6 15:00 /etc/alternatives/python3 -> /usr/bin/python3.9
# ll /usr/bin/python3.9
-rwxr-xr-x 1 root root 7776 Dec 21 2022 /usr/bin/python3.9
# alternatives --config python3
There are 2 programs which provide 'python3'.
Selection Command
-----------------------------------------------
* 1 /usr/bin/python3.6
+ 2 /usr/bin/python3.9
Enter to keep the current selection[+], or type selection number: 1
# python3 --version
Python 3.6.8
# ll /usr/bin/python3
lrwxrwxrwx. 1 root root 25 May 12 11:04 /usr/bin/python3 -> /etc/alternatives/python3
# ll /etc/alternatives/python3
lrwxrwxrwx 1 root root 18 Jul 7 10:46 /etc/alternatives/python3 -> /usr/bin/python3.6
如上所示,我們看到alternatvies其實是通過多一層軟鏈接,例如,/usr/bin/python3指向/etc/alternatives/python3,這一層關係不變, 切換python版本時,我們看到鏈接/etc/alternatives/python3 指向了不同的python版本來實現的。