编辑代码

#!/bin/bash
# Project: 服务器安装脚本
# Author: 林夕
# Update: 2024-09-10

# 软件下载路径
soft_path="linxi_soft"
# root_path=$PWD

# 软件远程下载地址
declare -A software_urls
software_urls["Nginx"]="https://mirrors.huaweicloud.com/nginx/nginx-1.25.5.tar.gz"
software_urls["Redis"]="https://mirrors.huaweicloud.com/redis/redis-6.2.7.tar.gz"
software_urls["Tomcat"]="https://mirrors.huaweicloud.com/apache/tomcat/tomcat-8/v8.5.96/bin/apache-tomcat-8.5.96.tar.gz"
software_urls["JAVA"]="https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz"
software_urls["JAVA21"]="https://mirrors.tuna.tsinghua.edu.cn/Adoptium/21/jdk/x64/linux/OpenJDK21U-jdk_x64_linux_hotspot_21.0.4_7.tar.gz"

# 下载软件安装包
download_soft() {
    check_network
    # 检查网络
    if [ $? -eq 0 ]; then
        local software=$1
        local url=${software_urls[$software]}
        local filename=$(basename "$url")
        # 检查 URL 是否以 "http://" 或 "https://" 开头
        if [[ $url =~ ^(https?://)(.*)$ ]]; then
            # 提取文件名
            if [[ ${BASH_REMATCH[2]} =~ /([^/]+)$ ]]; then
                filename="${BASH_REMATCH[1]}"
            else
                filename=""
            fi
        else
            filename=""
        fi
        echo "[检测软件] ${software}软件包"
        check_file_exists "$filename"
        local status=$?
        if [ $status -eq 2 ]; then
            filename=$url
        elif [ $status -ne 0 ]; then
            # 下载逻辑
            if which apt > /dev/null 2>&1; then
                url= $(echo "$url" | awk '{print $0}' | sed 's/rpm/deb/g')
            fi
            echo "[开始下载] ${software}软件包"
            sudo curl -O $url
            check_ok "[开始完成] ${software}软件包"
        fi
        echo "[开始安装] ${software}软件"
        # 安装函数
        install_$software "$filename"
    else
        # 如果无法连接到网络,则检测当前文件夹
        echo "无法连接到网络,检测当前文件夹..."
        install_$software "$filename"
fi
}

# 自动选择包管理软件并检查安装依赖
check_requirements() {
    if which yum > /dev/null 2>&1; then
        echo "[安装依赖] 开始安装基础依赖(RHEL/Rocky)!"
        for pkg in gcc tcl make wget curl pcre-devel zlib-devel openssl-devel libffi-devel sqlite-devel libaio; do
            if ! rpm -q $pkg > /dev/null 2>&1; then
                sudo yum install -y $pkg
                check_ok "[安装依赖] 安装依赖${pkg}"
            else
                echo "[安装依赖] 依赖${pkg}已经安装!"
            fi
        done
    fi
    if which apt > /dev/null 2>&1; then
        echo "[安装依赖] 开始安装基础依赖(Ubuntu/kali)!"
        for pkg in build-essential manpages-dev make wget curl libpcre++-dev libssl-dev zlib1g-dev; do
            if ! dpkg -l $pkg > /dev/null 2>&1; then
                sudo apt install -y $pkg
                check_ok "[安装依赖] 安装依赖${pkg}"
            else
                echo "[安装依赖] 依赖${pkg}已经安装!"
            fi
        done
    fi
}

# 运行状态处理
check_ok() {
    if [ $? -ne 0 ]; then
        echo "$1 错误:发生异常错误!!!"
        exit 1
    else
        echo "$1 成功:操作成功"
    fi
}

# 检查文件夹是否存在
check_dir_exists() {
    local dir="$1"
    if [ -d "$dir" ]; then
        echo "[文件夹检查] 文件夹 $dir 已存在!"
        return 0
    else
        echo "[文件夹检查] 文件夹 $dir 不存在!"
        mkdir "$dir"
        check_ok "[文件夹检查] ${dir}创建"
        return 1
    fi
}

# 定义检查网络连接的函数
check_network() {
    # 检测是否能够ping通8.8.8.8
    ping -c 1 8.8.8.8 > /dev/null 2>&1
    # 检查ping命令的返回码
    if [ $? -eq 0 ]; then
        echo "网络连接正常"
        return 0  # 返回0表示网络连接正常
    else
        echo "无法连接到网络"
        return 1  # 返回1表示无法连接到网络
    fi
}

# 获取系统信息
get_system_info() {
    # 获取发行版
    distribution=$(grep 'DISTRIB_ID' /etc/*release* | cut -d '=' -f2)
    # 获取版本号
    version=$(grep 'DISTRIB_RELEASE' /etc/*release* | cut -d '=' -f2)
    # 获取架构
    architecture=$(uname -m)
    # 判断发行版是否为空
    if [ -z "$distribution" ]; then
        # 获取发行版
        distribution=$(grep 'PRETTY_NAME' /etc/os-release | sed 's/PRETTY_NAME=//; s/"//g')
        # 获取版本号
        version=$(grep 'VERSION_ID' /etc/os-release | awk -F '=' '{print $2}' | sed 's/"//g')
        # 获取架构
        architecture=$(uname -m)
    fi
    # 输出结果
    echo "[系统信息] 发行版本: $distribution 版本号: $version 架构: $architecture"
}

# 主函数-菜单
main() {
    # 调用函数并获取返回值
    get_system_info
    software=()
    for key in "${!software_urls[@]}"; do
        software+=($key)
    done
    echo "支持安装的软件列表:(键入0退出)"
    for index in "${!software[@]}"
    do
        ((display_index = index + 1))
        if [ $display_index -lt 10 ]; then
            display_index="0$display_index"
        fi
        echo "$display_index. ${software[index]}"
    done
    read -p "请输入软件对应的数值(多个以空格分隔):" input
    if [ "$input" = "0" ]; then
        echo "[退出程序] 用户选择退出,程序结束。"
        exit 0
    fi
    if [ -d "$soft_path" ]; then
        echo "[软件路径] ${soft_path}文件夹已存在!"
        cd "$soft_path"
    else
        echo "[软件路径] ${soft_path}文件夹不存在。正在创建文件夹..."
        mkdir "$soft_path"
        check_ok "[软件路径] ${soft_path}创建"
        cd "$soft_path"
    fi
    indices=($input)
    check_requirements
    for index in "${indices[@]}"
    do
        cd $root_path/$soft_path
        if ((index >= 0 && index <= ${#software[@]})); then
            soft="${software[index-1]}"
            echo "[开始安装] 第${index-1}个软件: $soft"
            download_soft "$soft"
        else
            echo "[开始安装] 第${index-1}个软件: 不存在该软件"
        fi
        ((index++))
    done
}

main