这个问题问到点子上了!知其然还要知其所以然,这才是高级工程师的思维。
一句话总结原理:
update-alternatives 本质上是一个“符号链接(软链接)管理器”。它通过在系统里玩一个“三层套娃”的软链接游戏,让你用同一个命令(java)就能指向不同版本的真实程序。
用“接力棒”来理解
当你敲下 java -version 并回车时,系统其实经历了一场接力赛:
你敲的命令:java↓第1棒(PATH路径):/usr/bin/java ← 这是一个软链接↓第2棒(alternatives池):/etc/alternatives/java ← 这是另一个软链接(被切换的就是这里)↓第3棒(真正的程序):/usr/lib/jvm/java-17-openjdk-amd64/bin/java ← 真实文件
update-alternatives --config java 干的事,就是修改第2棒 /etc/alternatives/java 指向哪里。
用命令亲眼看看这个“套娃”
你可以在服务器上自己验证,执行这几条命令:
# 看第1棒指向哪ls -la /usr/bin/java# 输出类似:/usr/bin/java -> /etc/alternatives/java# 看第2棒指向哪(这就是被切换的那个)ls -la /etc/alternatives/java# 输出类似:/etc/alternatives/java -> /usr/lib/jvm/java-17-openjdk-amd64/bin/java# 看第3棒(真实文件)ls -la /usr/lib/jvm/java-17-openjdk-amd64/bin/java# 输出:这就是个真正的二进制可执行文件
当你运行 sudo update-alternatives --config java 并选了 Java 21 之后,第2棒就变成了:
/etc/alternatives/java -> /usr/lib/jvm/java-21-openjdk-amd64/bin/java
就这么简单! 第1棒永远不变,变的只是第2棒指向谁。
还有个“优先级”的隐藏玩法
你执行 update-alternatives --display java 会看到每个版本有个优先级数字:
update-alternatives --display java# 输出类似:# java - auto mode# link best version is /usr/lib/jvm/java-21-openjdk-amd64/bin/java (priority 2111)# link currently points to /usr/lib/jvm/java-17-openjdk-amd64/bin/java (priority 1711)
优先级规则:
- auto 模式(默认):系统自动选优先级最高的那个。你装了 Java 21(优先级2111),它比 Java 17(优先级1711)高,系统就自动切到 21。
- manual 模式(你手动选了之后):你手动选了 Java 17,系统就乖乖听你的,不再自动切了。
用 PHP 工程师熟悉的方式类比
这玩意儿其实跟你熟悉的 Composer 的全局命令 或者 NVM(Node Version Manager) 思路一样:
| 工具 | 管理方式 | 本质 |
|---|---|---|
update-alternatives |
修改 /etc/alternatives/ 下的软链接 |
系统级版本切换 |
nvm use 18 |
修改 ~/.nvm/current 的软链接 |
Node.js 版本切换 |
composer global |
修改 composer 的 bin 目录指向 | PHP 工具管理 |
总结
| 问题 | 答案 |
|---|---|
| 它改了什么? | 只改了 /etc/alternatives/java 这个软链接的指向 |
| 为什么能全局生效? | 因为 /usr/bin/java 永远指向 /etc/alternatives/java,所有用户都走这条路 |
| 会影响已运行的程序吗? | 不会! 已经跑起来的 Java 进程用的是启动时加载的那个版本,切换只影响新启动的程序 |
| 能管理其他命令吗? | 能!python、gcc、php 甚至 editor 都能用这玩意儿管 |
