linux中如何快速切换jdk版本
# 一. 背景
在我们平常的开发当中,我们想要测试不同jdk版本之间的一些新功能时,需要去切换jdk的版本,这个时候又需要去对应的环境变量中进行配置JAVA_HOME。但其实如果我们手动去更新的话,其实很麻烦。为了提供效率,我们可以写一个脚本,来更新我们的jdk版本。
# 二. shell脚本
前提:将对应的jdk目录放到/usr/local/下,例如:
①创建文件: source jdk_change.sh
#!/bin/bash
# 设置JDK安装目录
jdk_dir="/usr/local"
# 设置可用的JDK版本和路径
declare -A jdk_versions
jdk_versions["jdk8"]=$jdk_dir/jdk8
jdk_versions["jdk11"]=$jdk_dir/jdk11
jdk_versions["jdk17"]=$jdk_dir/jdk17
# 打印可用的JDK版本
echo "可用的JDK版本:"
for version in "${!jdk_versions[@]}"; do
echo "$version"
done
# 提示用户输入要切换的JDK版本
read -p "请输入要切换的JDK版本: " selected_version
# 检查用户输入的版本是否存在
if [[ ! "${jdk_versions[@]}" =~ "${selected_version}" ]]; then
echo "无效的JDK版本!"
exit 1
fi
# 设置新的JAVA_HOME和PATH
export JAVA_HOME="${jdk_versions[$selected_version]}"
export PATH="$JAVA_HOME/bin:$PATH"
# 打印切换后的JDK版本
echo "已切换至JDK版本: $selected_version"
java -version
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
②执行文件
source jdk_cahnge.sh
③注意事项: 上面的方法只能更改当前会话内的jdk环境变量,当我们重新通过ssh建立连接后,需要重新执行上面的脚本才可以生效。
# 三. 相关知识点
# 1. 什么是bash和shell
①shell shell是用户和Linux(或者更准确的说,是用户和Linux内核)之间的接口程序。你在提示符下输入的每个命令都由shell先解释然后传给Linux内核。 shell 是一个命令语言解释器(command-language interpreter)。拥有自己内建的 shell 命令集。此外,shell也能被系统中其他有效的Linux 实用程序和应用程序(utilities and application programs)所调用。 不论何时你键入一个命令,它都被Linux shell所解释。一些命令,比如打印当前工作目录命令(pwd),是包含在Linux bash内部的(就象DOS的内部命令)。其他命令,比如拷贝命令(cp)和移动命令(rm),是存在于文件系统中某个目录下的单独的程序。而对用户来说,你不知道(或者可能不关心)一个命令是建立在shell内部还是一个单独的程序。
- 首先检查命令是否是内部命令
- 不是的话再检查是否是一个应用程序,这里的应用程序可以是Linux本身的实用程序,比如ls rm,
- 然后shell试着在搜索路径($PATH)里寻找这些应用程序。搜索路径是一个能找到可执行程序的目录列表。
如果你键入的命令不是一个内部命令并且在路径里没有找到这个可执行文件,将会显示一条错误信息。而如果命令被成功的找到的话,shell的内部命令或应用程序将被分解为系统调用并传给Linux内核。
②bash Bourne Again shell (bash), 正如它的名字所暗示的,是 Bourne shell 的扩展。bash 与 Bourne shell 完全向后兼容,并且在 Bourne shell 的基础上增加和增强了很多特性。bash 也包含了很多 C 和 Korn shell 里的优点。bash 有很灵活和强大的编程接口,同时又有很友好的用户界面。 为什么要用 bash 来代替 sh 呢?Bourne shell 最大的缺点在于它处理用户的输入方面。在 Bourne shell 里键入命令会很麻烦,尤其当你键入很多相似的命令时。而 bash 准备了几种特性使命令的输入变得更容易。 这是几个最有用的bash内部命令: alias: 设置bash别名。 bg: 使一个被挂起的进程在后台继续执行。 cd: 改变当前工作目录。 exit: 终止shell。 export: 使变量的值对当前shell的所有子进程都可见 。 fc: 用来编辑历史命令列表里的命令。 fg: 使一个被挂起的进程在前台继续执行。 help: 显示bash内部命令的帮助信息。 kill: 终止某个进程。 pwd: 显示当前工作目录。 unalias: 删除已定义的别名。
所以我们执行sh xx.sh和bash xx.sh时,sh执行有时候会出现command not found找不到命令的报错,其实就是因为可能shell脚本里面有些命令是bash独有的,所以找不到,这个时候我们换成bash xx.sh来执行就可以了。例如declare命令就是bash独有的
# 2. 命令bash和source有什么区别
- 执行环境:source 命令在当前 Shell 环境中执行指定的脚本文件,而不会创建新的进程。这意味着脚本中的命令和设置会直接影响当前 Shell 环境,包括环境变量、函数定义、别名等。相反,bash 命令会创建一个新的 Bash Shell 进程,并在该进程中执行指定的脚本文件。脚本中的命令和设置只会影响新创建的进程,不会对当前 Shell 环境产生影响。
- 脚本路径:source 命令需要提供脚本文件的路径,并且该文件需要具有可执行权限。它会将指定的脚本文件作为当前 Shell 环境的一部分来执行。相比之下,bash 命令不要求脚本文件具有可执行权限,只需要提供脚本文件的路径即可。
- 脚本类型:source 命令主要用于执行 Bash 脚本文件(.sh),它是 Bash Shell 的内置命令。它会使用当前 Shell 解释器来执行脚本文件。而 bash 命令可以用于执行任何类型的脚本文件,包括 Bash 脚本、Shell 脚本以及其他脚本语言(如Python脚本、Perl脚本等)。它会创建一个新的 Bash Shell 进程来解释和执行脚本文件。
这也就是我们执行xx.sh时,如果里面有声明环境变量export时,如果我们使用bash,是无法在外面生效的原因,而执行source才能使当前连接的环境变量真正生效。
# 3. /etc/profile文件和我们手动执行source sh文件有什么区别吗
/etc/profile 文件是系统级别的配置文件,用于设置全局的环境变量和执行系统范围的初始化操作。当登录到系统时,无论是以交互方式登录还是通过远程连接登录,系统都会读取并执行 /etc/profile 文件。
而执行 source 命令来加载一个脚本文件时,该脚本文件通常是用户级别的,是特定用户为了满足自己的需求而创建的。用户可以在自己的脚本文件中定义和修改环境变量,以及执行其他个性化的设置。
主要区别如下:
- 范围:/etc/profile 文件中定义的环境变量是系统级别的,适用于所有用户,影响整个系统。而通过 source 命令加载的脚本文件中定义的环境变量是用户级别的,仅对当前用户有效。
- 权限:/etc/profile 文件通常由系统管理员管理和维护,因此需要相应的权限才能进行修改。而用户可以在自己的目录下创建脚本文件,并通过 source 命令加载,无需特殊权限。
- 优先级:当用户登录时,系统首先会执行 /etc/profile 文件,然后再执行用户的个人配置文件(如 ~/.bash_profile、~/.bashrc 等)。因此,在执行用户级别的脚本文件时,可以覆盖 /etc/profile 文件中定义的环境变量或进行个性化设置。
总之,/etc/profile 文件是系统级别的配置文件,用于设置全局的环境变量和执行系统范围的初始化操作。而通过 source 命令加载的个人脚本文件是用户级别的,用于定义用户特定的环境变量和执行个性化设置。
参考: 什么是Bash、什么是shell? (opens new window)
这个解答,解决了为什么我们手动执行xxx.sh里面的环境变量在其他的连接不生效的原因,因为其他ssh连接成果时,会自动执行/etc/profile文件。