# 通过alternatives进行多版本间切换
Date: 2020-06-28


上周在学习单点登录安装[CAS Overlay Template](https://github.com/apereo/cas-overlay-template)要使用指定版本,当时机器上安装了多个版本的jdk使用`alternatives`命令进行了切换.

如果需要在多个版本应用间切换并进行管理可以使用这个命令。

`alternative` 前身是 `Debian Linux`的一个用 `Perl`实现的工具 `update-alternatives` 后续`Red Hat`重写了并重新命名使用在 `Red Hat`and `CentOS`版本中.

`alternative`统一了有多个版本应用,但在`UNIX`中更认可通过环境变量来设置

> 通常定义在 `/etc/profile` 或 `$HOME/.profile`

下面用一个例子演示一下

如果有有一个应用 `em` ，他的新版本 `nem`, 由于习惯原因, 我们更习惯敲`em`， 可以通过下面步骤设置一下

### 创建

- 先创建两个脚本做为代表`em` `nem`应用

```Bash
[root@centosgpt alternatives]# cat em
#!/bin/bash
echo " This is em "
[root@centosgpt alternatives]# cat nem
#!/bin/bash
echo " This is nem "

```

- 生成一个`alternative`需要下面四个要素:

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

- link : 统一应用名称，一个链接文件
- name : `alternative` 的名称便于记忆
- path : 实际版本的路径
- priority :优先级

```Bash
[root@centosgpt alternatives]# sudo alternatives --install /usr/bin/em uemacs /root/alternatives/em 1
[root@centosgpt alternatives]# sudo alternatives --install /usr/bin/em uemacs /root/alternatives/nem 99
[root@centosgpt alternatives]# alternatives --config uemacs

There are 2 programs which provide 'uemacs'.

  Selection    Command
-----------------------------------------------
 + 1           /root/alternatives/em
*  2           /root/alternatives/nem

```

- 验证

```Bash
[root@centosgpt ~]# em
 This is nem

[root@centosgpt ~]# alternatives --config uemacs

There are 2 programs which provide &#039;uemacs&#039;.

  Selection    Command
-----------------------------------------------
   1           /root/alternatives/em
*+ 2           /root/alternatives/nem

Enter to keep the current selection[+], or type selection number: 1
[root@centosgpt ~]# em
 This is em

```

### 移除

`alternatives --remove <name> <path>`

```Bash
[root@centosgpt alternatives]# sudo alternatives --remove uemacs  /root/alternatives/nem
[root@centosgpt alternatives]# sudo alternatives --config uemacs

There is 1 program that provides 'uemacs'.

  Selection    Command
-----------------------------------------------
*+ 1           /root/alternatives/em

Enter to keep the current selection[+], or type selection number:
[root@centosgpt alternatives]# sudo alternatives --remove uemacs  /root/alternatives/em
[root@centosgpt alternatives]# sudo alternatives --config uemacs

```

### 异常处理

```Bash
[root@centosgpt alternatives]# sudo alternatives --install /user/bin/em uemacs /root/alternatives/em 1
failed to link /user/bin/em -> /etc/alternatives/uemacs: /user/bin/em exists and it is not a symlink
[root@centosgpt alternatives]# sudo alternatives --install /usr/bin/em uemacs /root/alternatives/em 1
the primary link for uemacs must be /user/bin/em
```

由于第一个创建时链接文件名写错了， 报错了, 进下面的路径看下

```Bash
[root@centosgpt alternatives]# pwd
/var/lib/alternatives
[root@centosgpt alternatives]# pwd
/var/lib/alternatives
[root@centosgpt alternatives]# ls -l uemacs
-rw-r--r--. 1 root root 43 Jun 28 10:32 uemacs

```

看下内容, 里面存了错误的链接名:

```C
[root@centosgpt alternatives]# cat uemacs
auto
/user/bin/em

/root/alternatives/em
1
[root@centosgpt alternatives]#

```

删掉他重新做

```Bash
[root@centosgpt alternatives]# sudo alternatives --install /usr/bin/em uemacs /root/alternatives/em 1

[root@centosgpt alternatives]# sudo alternatives --config uemacs

There is 1 program that provides 'uemacs'.

  Selection    Command
-----------------------------------------------
*+ 1           /root/alternatives/em

```

### 参考及引用

[Introduction to the alternatives command in Linux](https://www.redhat.com/sysadmin/alternatives-command)

