#!/usr/bin/env bash
# --------------------------------------------------
# OpenJDK 一键安装脚本(Rocky Linux 优化版)
# 版本:3.0
# 更新:2024-06-12
# 支持:Rocky Linux 9.x / RHEL 9.x
# --------------------------------------------------
# 启用严格模式(错误退出/未设变量检测/管道失败)
set -euo pipefail
shopt -s inherit_errexit
trap 'cleanup $?' EXIT
# -------------------- 全局配置 --------------------
WORK_DIR="/opt" # 工作目录
JAVA_VER="11.0.2" # Java版本号
JAVA_PATH="/usr/java" # 安装路径
MIRROR_URL="https://mirrors.huaweicloud.com/openjdk/${JAVA_VER}/openjdk-${JAVA_VER}_linux-x64_bin.tar.gz"
LOG_FILE="/var/log/jdk_install_$(date +%Y%m%d%H%M%S).log" # 带时间戳的日志文件
MIN_SPACE=500 # 最小所需磁盘空间(MB)
# -------------------- 初始化日志 --------------------
exec 3>&1 4>&2
exec > >(tee -a "${LOG_FILE}") 2>&1
# -------------------- 颜色输出函数 --------------------
print_color() {
local color=$1
local msg=$2
local no_color='\033[0m'
# 非交互式终端禁用颜色
if [[ ! -t 1 ]]; then
echo "${msg}"
return
fi
case "${color}" in
red) echo -e "\033[31m${msg}${no_color}" ;;
green) echo -e "\033[32m${msg}${no_color}" ;;
yellow) echo -e "\033[33m${msg}${no_color}" ;;
blue) echo -e "\033[34m${msg}${no_color}" ;;
*) echo -e "${msg}" ;;
esac
}
# -------------------- 清理函数 --------------------
cleanup() {
local exit_code=$1
if [[ ${exit_code} -ne 0 ]]; then
print_color "red" "\n[!] 安装失败!退出码:${exit_code}"
print_color "yellow" "[+] 查看完整日志:tail -n 50 ${LOG_FILE}"
[[ -f "${WORK_DIR}/.tmp_download" ]] && rm -f "${WORK_DIR}/.tmp_download"
fi
}
# -------------------- 系统检查 --------------------
check_system() {
print_color "blue" "[1/6] 系统环境检查..."
# 发行版检测
if ! grep -q 'Rocky Linux' /etc/redhat-release 2>/dev/null; then
print_color "yellow" "[!] 非Rocky Linux系统,部分优化可能不生效"
fi
# 内核版本
local kernel_ver
kernel_ver=$(uname -r)
print_color "blue" "|- 内核版本:${kernel_ver}"
# 系统架构
if [[ $(uname -m) != "x86_64" ]]; then
print_color "red" "[!] 仅支持x86_64架构"
exit 1
fi
}
# -------------------- 依赖检查 --------------------
check_dependencies() {
print_color "blue" "[2/6] 检查系统依赖..."
local deps=("wget" "tar" "gzip")
local missing=()
for cmd in "${deps[@]}"; do
if ! command -v "${cmd}" &>/dev/null; then
missing+=("${cmd}")
fi
done
if [[ ${#missing[@]} -gt 0 ]]; then
print_color "yellow" "|- 缺少依赖:${missing[*]}"
print_color "blue" "|- 正在安装依赖..."
if ! dnf install -y "${missing[@]}" >> "${LOG_FILE}" 2>&1; then
print_color "red" "[!] 依赖安装失败"
exit 1
fi
fi
}
# -------------------- 环境预检 --------------------
precheck() {
print_color "blue" "[3/6] 执行环境预检..."
# 磁盘空间检查
local free_space
free_space=$(df -m "${WORK_DIR}" | awk 'NR==2 {print $4}')
if [[ ${free_space} -lt ${MIN_SPACE} ]]; then
print_color "red" "|- 磁盘空间不足!需要 ${MIN_SPACE}MB,可用 ${free_space}MB"
exit 1
fi
# 目录可写性检查
if ! touch "${WORK_DIR}/.write_test" 2>/dev/null; then
print_color "red" "|- 目录不可写:${WORK_DIR}"
exit 1
fi
rm -f "${WORK_DIR}/.write_test"
# SELinux状态检查
if [[ $(getenforce) == "Enforcing" ]]; then
print_color "yellow" "|- SELinux处于强制模式,可能影响安装"
fi
}
# -------------------- 下载模块 --------------------
download_jdk() {
print_color "blue" "[4/6] 开始下载JDK..."
local file_name="openjdk-${JAVA_VER}_linux-x64_bin.tar.gz"
local tmp_file="${WORK_DIR}/.tmp_download"
# 清理旧文件
[[ -f "${WORK_DIR}/${file_name}" ]] && rm -f "${WORK_DIR}/${file_name}"
# 使用临时文件下载(避免残留)
if ! wget -c -q --progress=dot:giga "${MIRROR_URL}" -O "${tmp_file}"; then
print_color "red" "|- 下载失败!请检查:"
print_color "red" " |- 网络连接:ping mirrors.huaweicloud.com"
print_color "red" " |- 手动测试:wget '${MIRROR_URL}'"
exit 1
fi
# 重命名正式文件
mv "${tmp_file}" "${WORK_DIR}/${file_name}"
print_color "green" "|- 下载成功 → ${WORK_DIR}/${file_name}"
print_color "blue" "|- 文件大小:$(du -sh ${WORK_DIR}/${file_name} | cut -f1)"
}
# -------------------- 安装模块 --------------------
install_jdk() {
print_color "blue" "[5/6] 安装JDK ${JAVA_VER}..."
local file_name="openjdk-${JAVA_VER}_linux-x64_bin.tar.gz"
local jdk_dir="jdk-${JAVA_VER}"
# 清理旧安装
[[ -d "${JAVA_PATH}" ]] && rm -rf "${JAVA_PATH}"
mkdir -p "${JAVA_PATH}"
# 解压文件
if ! tar -xzf "${WORK_DIR}/${file_name}" -C "${JAVA_PATH}"; then
print_color "red" "|- 解压失败!可能文件损坏"
print_color "yellow" "|- 建议手动验证:tar -tzf ${WORK_DIR}/${file_name}"
exit 1
fi
# 权限修复
chown -R root:root "${JAVA_PATH}"
chmod -R 755 "${JAVA_PATH}"
}
# -------------------- 配置模块 --------------------
configure_env() {
print_color "blue" "[6/6] 配置环境变量..."
local profile_file="/etc/profile.d/jdk.sh"
local jdk_path="${JAVA_PATH}/jdk-${JAVA_VER}"
# 生成配置文件
cat > "${profile_file}" << EOF
# OpenJDK Environment
export JAVA_HOME="${jdk_path}"
export PATH="\$JAVA_HOME/bin:\$PATH"
export CLASSPATH=".:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar"
EOF
# 立即生效
source "${profile_file}"
# 验证配置
if ! java -version >> "${LOG_FILE}" 2>&1; then
print_color "red" "|- 环境配置失败!"
print_color "yellow" "|- 手动验证命令:source ${profile_file} && java -version"
exit 1
fi
}
# -------------------- 主函数 --------------------
main() {
clear
print_color "green" "开始 OpenJDK ${JAVA_VER} 安装流程"
check_system
check_dependencies
precheck
download_jdk
install_jdk
configure_env
# 最终验证
local installed_ver
installed_ver=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}')
print_color "green" "\n✅ 安装成功!Java版本:${installed_ver}"
}
# -------------------- 执行入口 --------------------
main
exit 0
最后修改:2025 年 02 月 21 日
© 允许规范转载
8 条评论
作者对主题的挖掘深入骨髓,展现了非凡的洞察力和理解力。
作者的才华横溢,让这篇文章成为了一篇不可多得的艺术品。
?语言类评语?
每一个段落都紧密相连,逻辑清晰,展现了作者高超的写作技巧。
作者的观点新颖且实用,让人在阅读中获得了新的思考和灵感。
结论部分可提出实际应用建议,提升价值。
作者以非凡的视角解读平凡,让文字焕发出别样的光彩。
内容的丰富性和深度让人仿佛置身于知识的海洋,受益匪浅。