JDK 自动安装脚本

JDK 自动安装脚本

功能说明

自动化安装 JDK 的 Shell 脚本,支持多版本、多架构,适用于单机部署和 Ansible 批量部署场景。

支持版本

  • JDK 8 (包含 JRE_HOME)
  • JDK 11
  • JDK 17

支持架构

  • AMD64 (x86_64)
  • ARM64 (aarch64)

已验证系统

脚本已在以下 Linux 发行版上测试通过:

  • CentOS 7
  • CentOS 8
  • Rocky Linux 8
  • Kylin Linux Advanced Server V10 (Halberd) – 麒麟操作系统

理论上支持所有基于 RHEL 的 Linux 发行版。

image-20260306152332801

目录结构

jdk_install/
├── jdk8/                           # JDK 8 安装包目录
│   ├── jdk-8u421-linux-x64.tar.gz
│   └── jdk-8u421-linux-aarch64.tar.gz
├── jdk11/                          # JDK 11 安装包目录
│   ├── jdk-11.0.24_linux-x64_bin.tar.gz
│   └── jdk-11.0.24_linux-aarch64_bin.tar.gz
├── jdk17/                          # JDK 17 安装包目录
│   ├── jdk-17.0.18_linux-x64_bin.tar.gz
│   └── jdk-17.0.18_linux-aarch64_bin.tar.gz
├── jdk_install.sh                  # 安装脚本
└── README.md                       # 说明文档

使用方法

1. 交互式安装

# 添加执行权限
chmod +x jdk_install.sh

# 以 root 用户运行
sudo ./jdk_install.sh

# 根据提示输入版本号 (8/11/17)

2. 命令行自动安装

# 安装 JDK 8
sudo ./jdk_install.sh 8

# 安装 JDK 11
sudo ./jdk_install.sh 11

# 安装 JDK 17
sudo ./jdk_install.sh 17

3. Ansible 批量部署

# playbook 示例
- name: 批量安装 JDK 11
  hosts: all
  tasks:
    - name: 上传 JDK 安装脚本和安装包
      copy:
        src: jdk_install/
        dest: /tmp/jdk_install/
        mode: '0755'

    - name: 执行安装脚本
      shell: /tmp/jdk_install/jdk_install.sh 11
      args:
        chdir: /tmp/jdk_install

或使用 script 模块:

- name: 安装 JDK 11
  script: jdk_install/jdk_install.sh 11

安装过程

脚本会自动完成以下操作:

  1. 检测系统架构(AMD64/ARM64)
  2. 根据版本选择对应的安装包
  3. 检查是否已安装 JDK(自动模式跳过确认)
  4. 解压安装包到 /usr/local/
  5. 创建软链接 /usr/local/jdk(备份旧版本)
  6. 配置环境变量到 /etc/profile.d/jdk.sh
  7. 验证安装是否成功

环境变量配置

JDK 8 及更早版本

export JAVA_HOME=/usr/local/jdk
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

JDK 9 及更高版本 (JDK 11, 17 等)

export JAVA_HOME=/usr/local/jdk
export CLASSPATH=.:${JAVA_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

注意:JDK 9 开始移除了独立的 JRE 目录,因此不再需要配置 JRE_HOME。

安装后操作

安装完成后,环境变量会自动生效。如果在当前终端无法使用 java 命令,请手动加载:

source /etc/profile.d/jdk.sh

验证安装:

java -version
javac -version
echo $JAVA_HOME

版本切换

如果需要切换 JDK 版本,只需重新运行脚本安装新版本即可。脚本会:

  1. 备份旧的软链接(如 jdk.bak.20260306143025
  2. 备份旧的环境变量配置(如 jdk.sh.bak.20260306143025
  3. 创建新的软链接和环境变量配置

手动切换版本:

# 查看已安装的版本
ls -l /usr/local/ | grep jdk

# 切换到其他版本(修改软链接)
rm -f /usr/local/jdk
ln -s /usr/local/jdk-11.0.24 /usr/local/jdk

# 重新加载环境变量
source /etc/profile.d/jdk.sh

卸载 JDK

# 删除 JDK 目录
rm -rf /usr/local/jdk*

# 删除环境变量配置
rm -f /etc/profile.d/jdk.sh*

# 重新加载环境变量
source /etc/profile

注意事项

  1. 脚本需要 root 权限运行
  2. 确保安装包文件存在于对应的版本目录中
  3. 自动安装模式会跳过已有 JDK 的确认提示
  4. 安装过程会自动备份旧版本,不会丢失数据
  5. JDK 8 及更早版本包含 JRE_HOME,JDK 9+ 不包含

故障排查

问题:找不到安装包

错误: JDK 安装包 /path/to/jdk_install/jdk11/jdk-11.0.24_linux-x64_bin.tar.gz 不存在。

解决方法:
– 检查安装包是否存在于对应的版本目录
– 确认文件名是否正确
– 检查文件权限

问题:java 命令不可用

解决方法:

# 手动加载环境变量
source /etc/profile.d/jdk.sh

# 或重新登录终端

问题:权限不足

错误: 请使用 root 用户运行此脚本。

解决方法:

sudo ./jdk_install.sh 11

更新日志

  • 2026-03-06: 初始版本
    • 支持 JDK 8/11/17 自动安装
    • 支持 AMD64 和 ARM64 架构自动识别
    • 支持命令行参数和 Ansible 批量部署
    • 已验证系统:CentOS 7/8、Rocky Linux 8、麒麟 V10

脚本如下

#!/bin/bash
# JDK 自动安装脚本
# 支持 JDK8、JDK11、JDK17,支持 AMD64 和 ARM64 架构
#
# 使用方法:
#   交互式安装: ./jdk_install.sh
#   自动安装:   ./jdk_install.sh [版本号]
#
# 版本号参数:
#   8  -> 安装 JDK 8
#   11 -> 安装 JDK 11
#   17 -> 安装 JDK 17
#
# 示例:
#   ./jdk_install.sh 8    # 自动安装 JDK 8
#   ./jdk_install.sh 11   # 自动安装 JDK 11
#   ./jdk_install.sh 17   # 自动安装 JDK 17
#
# Ansible 批量部署示例:
#   ansible all -m script -a "jdk_install.sh 11"
#
# 开启严格模式,遇到错误立即退出
set -e

# 定义当前脚本所在目录
DIR=$(cd "$(dirname "$0")" && pwd)

# 定义日志函数,方便输出日志信息
log() {
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $1"
}

# 检测系统架构
detect_architecture() {
    ARCH=$(uname -m)
    case "$ARCH" in
        x86_64)
            ARCH_TYPE="x64"
            log "检测到系统架构: AMD64 (x86_64)"
            ;;
        aarch64)
            ARCH_TYPE="aarch64"
            log "检测到系统架构: ARM64 (aarch64)"
            ;;
        *)
            log "错误: 不支持的架构 $ARCH,退出安装。"
            exit 1
            ;;
    esac
}

# 选择 JDK 版本
select_jdk_version() {
    # 如果通过命令行参数指定了版本,直接使用
    if [ -n "$1" ]; then
        choice="$1"
        log "通过命令行参数指定 JDK 版本: $choice"
    else
        # 交互式选择版本
        echo ""
        echo "=========================================="
        echo "请选择要安装的 JDK 版本:"
        echo "支持版本: 8, 11, 17"
        echo "=========================================="
        read -p "请输入 JDK 版本号 (8/11/17): " choice
    fi

    case "$choice" in
        8)
            JDK_VERSION="8"
            if [ "$ARCH_TYPE" = "x64" ]; then
                JDK_PACKAGE="jdk-8u421-linux-x64.tar.gz"
                JDK_DIR_NAME="jdk1.8.0_421"
            else
                JDK_PACKAGE="jdk-8u421-linux-aarch64.tar.gz"
                JDK_DIR_NAME="jdk1.8.0_421"
            fi
            log "已选择: JDK 8"
            ;;
        11)
            JDK_VERSION="11"
            if [ "$ARCH_TYPE" = "x64" ]; then
                JDK_PACKAGE="jdk-11.0.24_linux-x64_bin.tar.gz"
                JDK_DIR_NAME="jdk-11.0.24"
            else
                JDK_PACKAGE="jdk-11.0.24_linux-aarch64_bin.tar.gz"
                JDK_DIR_NAME="jdk-11.0.24"
            fi
            log "已选择: JDK 11"
            ;;
        17)
            JDK_VERSION="17"
            if [ "$ARCH_TYPE" = "x64" ]; then
                JDK_PACKAGE="jdk-17.0.18_linux-x64_bin.tar.gz"
                JDK_DIR_NAME="jdk-17.0.18"
            else
                JDK_PACKAGE="jdk-17.0.18_linux-aarch64_bin.tar.gz"
                JDK_DIR_NAME="jdk-17.0.18"
            fi
            log "已选择: JDK 17"
            ;;
        *)
            log "错误: 无效的版本号 '$choice',退出安装。"
            log "支持的版本: 8, 11, 17"
            exit 1
            ;;
    esac

    # 根据 JDK 版本动态设置子目录路径
    JDK_SUBDIR="${DIR}/jdk${JDK_VERSION}"
}

# 检查 JDK 安装包是否存在
check_jdk_package() {
    JDK_FILE="${JDK_SUBDIR}/${JDK_PACKAGE}"
    if [ ! -f "$JDK_FILE" ]; then
        log "错误: JDK 安装包 $JDK_FILE 不存在。"
        log "请确认文件路径: ${JDK_SUBDIR}/"
        exit 1
    fi
    log "找到 JDK 安装包: $JDK_FILE"
}

# 检查是否已安装 JDK
check_existing_jdk() {
    if command -v java &> /dev/null; then
        CURRENT_JAVA_VERSION=$(java -version 2>&1 | head -n 1)
        log "警告: 系统中已存在 Java 环境: $CURRENT_JAVA_VERSION"

        # 如果是非交互模式(通过命令行参数),自动跳过确认
        if [ -n "$AUTO_INSTALL" ]; then
            log "自动安装模式,继续安装..."
            return 0
        fi

        read -p "是否继续安装? (y/n): " continue_install
        if [ "$continue_install" != "y" ] && [ "$continue_install" != "Y" ]; then
            log "用户取消安装,退出。"
            exit 0
        fi
    fi
}

# 安装 JDK
install_jdk() {
    log "=========================================="
    log "开始安装 JDK ${JDK_VERSION}..."
    log "=========================================="

    # 移动 JDK 安装包到 /usr/local/
    log "复制 JDK 安装包到 /usr/local/ ..."
    cp "$JDK_FILE" /usr/local/

    # 切换到 /usr/local/ 目录
    cd /usr/local/

    # 解压 JDK 安装包
    log "解压 JDK 安装包..."
    tar -zxvf "$JDK_PACKAGE" > /dev/null 2>&1

    # 删除压缩包
    log "删除压缩包..."
    rm -f "$JDK_PACKAGE"

    # 创建软链接(可选,方便版本管理)
    # 如果已存在 JDK 软链接,先备份
    if [ -L /usr/local/jdk ]; then
        log "检测到旧的 JDK 软链接,进行备份..."
        OLD_JDK_TARGET=$(readlink /usr/local/jdk)
        mv /usr/local/jdk /usr/local/jdk.bak.$(date +%Y%m%d%H%M%S)
        log "旧软链接已备份 (原指向: ${OLD_JDK_TARGET})"
    elif [ -d /usr/local/jdk ] && [ ! -L /usr/local/jdk ]; then
        # 如果是真实目录而不是软链接,也进行备份
        log "检测到旧的 JDK 目录,进行备份..."
        mv /usr/local/jdk /usr/local/jdk.bak.$(date +%Y%m%d%H%M%S)
        log "旧 JDK 目录已备份"
    fi
    ln -s "/usr/local/${JDK_DIR_NAME}" /usr/local/jdk
    log "创建软链接: /usr/local/jdk -> /usr/local/${JDK_DIR_NAME}"
}

# 配置环境变量
configure_environment() {
    log "配置 JDK 环境变量..."

    # 备份旧的配置文件(如果存在)
    if [ -f /etc/profile.d/jdk.sh ]; then
        log "备份旧的 JDK 配置文件..."
        mv /etc/profile.d/jdk.sh /etc/profile.d/jdk.sh.bak.$(date +%Y%m%d%H%M%S)
    fi

    # 创建新的环境变量配置文件
    log "创建 JDK 环境变量配置文件..."

    # JDK 8 及更早版本有独立的 JRE 目录,JDK 11+ 没有
    if [ "$JDK_VERSION" -le 8 ]; then
        # JDK 8 及更早版本有独立的 JRE 目录
        cat > /etc/profile.d/jdk.sh << EOF
# JDK ${JDK_VERSION} 环境变量配置
export JAVA_HOME=/usr/local/jdk
export JRE_HOME=\${JAVA_HOME}/jre
export CLASSPATH=.:\${JAVA_HOME}/lib:\${JRE_HOME}/lib
export PATH=\${JAVA_HOME}/bin:\$PATH
EOF
    else
        # JDK 11+ 没有独立的 JRE 目录
        cat > /etc/profile.d/jdk.sh << EOF
# JDK ${JDK_VERSION} 环境变量配置
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=.:\${JAVA_HOME}/lib
export PATH=\${JAVA_HOME}/bin:\$PATH
EOF
    fi

    # 添加执行权限
    chmod a+x /etc/profile.d/jdk.sh
    log "环境变量配置文件已创建: /etc/profile.d/jdk.sh"

    # 加载环境变量
    source /etc/profile.d/jdk.sh
    log "环境变量已加载"
}

# 验证安装
verify_installation() {
    log "=========================================="
    log "验证 JDK 安装..."
    log "=========================================="

    # 刷新环境变量,确保使用最新配置
    log "刷新环境变量..."
    source /etc/profile.d/jdk.sh

    # 验证 Java 命令是否可用
    if command -v java &> /dev/null; then
        log "JDK 安装成功!"
        echo ""
        echo "=========================================="
        echo "Java 版本信息:"
        echo "=========================================="
        java -version
        echo ""
        echo "=========================================="
        echo "环境变量信息:"
        echo "=========================================="
        echo "JAVA_HOME: ${JAVA_HOME}"
        echo "PATH: ${PATH}" | grep --color=never "${JAVA_HOME}"
        echo ""

        # 验证 javac 是否可用
        if command -v javac &> /dev/null; then
            log "javac 编译器可用"
        else
            log "警告: javac 编译器不可用"
        fi

        echo "=========================================="
        log "安装完成!环境变量已生效。"
        log "如果在当前终端无法使用 java 命令,请执行:"
        log "source /etc/profile.d/jdk.sh"
        echo "=========================================="
    else
        log "错误: JDK 安装失败,java 命令不可用。"
        log "请检查安装日志并手动执行: source /etc/profile.d/jdk.sh"
        exit 1
    fi
}

# 主函数
main() {
    log "=========================================="
    log "JDK 自动安装脚本"
    log "=========================================="

    # 检查是否为 root 用户
    if [ "$EUID" -ne 0 ]; then
        log "错误: 请使用 root 用户运行此脚本。"
        exit 1
    fi

    # 解析命令行参数
    JDK_VERSION_ARG=""
    if [ $# -gt 0 ]; then
        JDK_VERSION_ARG="$1"
        AUTO_INSTALL="yes"
        log "检测到命令行参数,启用自动安装模式"
    fi

    # 检测系统架构
    detect_architecture

    # 选择 JDK 版本(支持命令行参数)
    select_jdk_version "$JDK_VERSION_ARG"

    # 检查 JDK 安装包
    check_jdk_package

    # 检查已存在的 JDK
    check_existing_jdk

    # 安装 JDK
    install_jdk

    # 配置环境变量
    configure_environment

    # 验证安装
    verify_installation

    log "=========================================="
    log "JDK 安装完成!"
    log "=========================================="
}

# 执行主函数
main "$@"

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇