lskypro兰空图床安装libvips库一键脚本 需在/opt目录

安装说明:

  1. 保存为install_libvips.sh
  2. 赋予权限:chmod +x install_libvips.sh
  3. 运行:sudo ./install_libvips.sh

特点说明:

  • 针对宝塔环境的全系统适配超级懒人版一键安装脚本,已优化依赖处理逻辑,支持主流 Linux 发行版(包括宝塔常用的 CentOS、Ubuntu、Debian),无需手动干预任何步骤:
#!/bin/bash
# ==============================================================
# 全功能libvips一键安装脚本 v2.0
# 支持系统: CentOS 6+/Ubuntu 16+/Debian 8+ (含宝塔面板环境)
# 目标版本: 8.17.2
# 特性: 全自动化安装、多系统适配、详细日志、错误处理、环境优化
# ==============================================================

# ==============================================================
# 初始化环境与变量
# ==============================================================
# 确保脚本以root权限运行
if [ "$(id -u)" -ne 0 ]; then
    echo -e "\033[31m错误: 请使用root权限运行此脚本\033[0m"
    echo -e "\033[33m正确命令: sudo $0\033[0m"
    exit 1
fi

# 基础变量定义
VIPS_VERSION="8.17.2"
BASE_DIR="/usr/local"
TMP_DIR="/tmp/vips_install_$(date +%Y%m%d_%H%M%S)"
LOG_DIR="/var/log/vips_install"
LOG_FILE="${LOG_DIR}/install_$(date +%Y%m%d_%H%M%S).log"
PKG_MANAGER=""
DISTRO=""
DISTRO_VERSION=""
CPU_CORES=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 2)
RETRY_COUNT=3
SUCCESS=0

# 创建必要目录
mkdir -p "$TMP_DIR"
mkdir -p "$LOG_DIR"

# 重定向输出到日志和终端
exec > >(tee -a "$LOG_FILE") 2>&1

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # 无颜色

# ==============================================================
# 日志与输出函数
# ==============================================================
# 显示标题
show_title() {
    echo -e "\n${CYAN}==============================================================${NC}"
    echo -e "${CYAN}== $1${NC}"
    echo -e "${CYAN}==============================================================${NC}\n"
}

# 显示进度
show_progress() {
    echo -e "\n${BLUE}===== $1 =====${NC}\n"
}

# 信息提示
info() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] ${BLUE}INFO${NC}: $1"
}

# 成功提示
success() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] ${GREEN}SUCCESS${NC}: $1"
}

# 警告提示
warn() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] ${YELLOW}WARN${NC}: $1"
}

# 错误提示
error() {
    echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] ${RED}ERROR${NC}: $1"
}

# 错误处理并退出
error_exit() {
    error "$1"
    error "安装失败,请查看日志获取详细信息: $LOG_FILE"
    error "尝试解决方案:"
    error "1. 检查网络连接是否正常"
    error "2. 确保系统已更新到最新版本"
    error "3. 清理缓存后重试 (yum clean all 或 apt clean)"
    error "4. 手动安装缺失的依赖包"
    
    # 清理临时文件
    clean_up
    
    exit 1
}

# ==============================================================
# 系统检测函数
# ==============================================================
detect_system() {
    show_title "系统环境检测"
    info "开始检测系统环境..."
    
    # 检测发行版
    if [ -f /etc/redhat-release ]; then
        DISTRO="centos"
        DISTRO_VERSION=$(cat /etc/redhat-release | grep -oE '[0-9]+\.[0-9]+' | cut -d'.' -f1)
        
        # 检测包管理器
        if command -v dnf &>/dev/null; then
            PKG_MANAGER="dnf"
        elif command -v yum &>/dev/null; then
            PKG_MANAGER="yum"
        else
            error_exit "未找到可用的包管理器 (yum/dnf)"
        fi
    elif [ -f /etc/lsb-release ]; then
        . /etc/lsb-release
        DISTRO="$DISTRIB_ID"
        DISTRO_VERSION="$DISTRIB_RELEASE"
        PKG_MANAGER="apt"
    elif [ -f /etc/debian_version ]; then
        DISTRO="debian"
        DISTRO_VERSION=$(cat /etc/debian_version | cut -d'.' -f1)
        PKG_MANAGER="apt"
    else
        error_exit "不支持的操作系统,仅支持CentOS/Ubuntu/Debian"
    fi
    
    # 转换为小写
    DISTRO=$(echo "$DISTRO" | tr '[:upper:]' '[:lower:]')
    
    # 显示检测结果
    info "检测到操作系统: $DISTRO"
    info "操作系统版本: $DISTRO_VERSION"
    info "包管理器: $PKG_MANAGER"
    info "CPU核心数: $CPU_CORES"
    info "临时目录: $TMP_DIR"
    info "日志文件: $LOG_FILE"
    
    # 检测宝塔环境
    if [ -d "/www/server/panel" ]; then
        info "检测到宝塔面板环境,将进行特殊优化"
        BAOTA_ENV=1
    else
        BAOTA_ENV=0
        warn "未检测到宝塔面板环境,将进行常规安装"
    fi
    
    # 检测系统版本兼容性
    check_system_compatibility
    
    success "系统环境检测完成"
}

# 检查系统版本兼容性
check_system_compatibility() {
    info "检查系统版本兼容性..."
    
    case "$DISTRO" in
        "centos")
            if [ "$DISTRO_VERSION" -lt 6 ]; then
                error_exit "CentOS版本过低,需要CentOS 6或更高版本"
            elif [ "$DISTRO_VERSION" -eq 6 ]; then
                warn "CentOS 6已接近生命周期结束,可能存在兼容性问题"
            fi
            ;;
        "ubuntu")
            if ! echo "$DISTRO_VERSION" | grep -qE '^16\.|^18\.|^20\.|^22\.'; then
                error_exit "Ubuntu版本不支持,需要Ubuntu 16.04或更高版本"
            fi
            ;;
        "debian")
            if [ "$DISTRO_VERSION" -lt 8 ]; then
                error_exit "Debian版本过低,需要Debian 8或更高版本"
            fi
            ;;
    esac
}

# ==============================================================
# 系统预处理函数
# ==============================================================
system_prepare() {
    show_title "系统环境预处理"
    info "开始系统环境预处理..."
    
    # 临时关闭SELinux
    if command -v getenforce &>/dev/null && [ "$(getenforce)" != "Disabled" ]; then
        info "临时关闭SELinux..."
        setenforce 0 >/dev/null 2>&1 || warn "关闭SELinux失败,可能需要手动处理"
    fi
    
    # 临时关闭防火墙(避免影响下载)
    if command -v systemctl &>/dev/null; then
        if systemctl is-active --quiet firewalld; then
            info "临时关闭firewalld..."
            systemctl stop firewalld >/dev/null 2>&1
            FIREWALLD_RUNNING=1
        fi
    elif command -v service &>/dev/null; then
        if service iptables status >/dev/null 2>&1; then
            info "临时关闭iptables..."
            service iptables stop >/dev/null 2>&1
            IPTABLES_RUNNING=1
        fi
    fi
    
    # 设置超时时间
    info "设置网络超时参数..."
    export TMOUT=300
    echo "$TMOUT" > /proc/sys/net/ipv4/tcp_retries2
    
    success "系统环境预处理完成"
}

# ==============================================================
# 依赖安装函数
# ==============================================================
install_dependencies() {
    show_title "安装依赖包"
    info "开始安装所需依赖包..."
    
    case "$PKG_MANAGER" in
        "yum"|"dnf")
            install_deps_rpm
            ;;
        "apt")
            install_deps_deb
            ;;
        *)
            error_exit "不支持的包管理器: $PKG_MANAGER"
            ;;
    esac
    
    success "所有依赖包安装完成"
}

# RPM系系统依赖安装 (CentOS)
install_deps_rpm() {
    info "使用$PKG_MANAGER安装依赖包..."
    
    # 安装必要的软件源
    info "配置必要的软件源..."
    
    # 安装EPEL源
    if ! rpm -qa | grep -q "epel-release"; then
        info "安装EPEL软件源..."
        retry_command "$PKG_MANAGER install -y epel-release" $RETRY_COUNT || {
            info "尝试备用方式安装EPEL源..."
            local epel_url
            if [ "$DISTRO_VERSION" -eq 7 ]; then
                epel_url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm"
            elif [ "$DISTRO_VERSION" -eq 8 ]; then
                epel_url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm"
            elif [ "$DISTRO_VERSION" -eq 9 ]; then
                epel_url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm"
            else
                epel_url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm"
            fi
            
            retry_command "rpm -Uvh $epel_url" $RETRY_COUNT || {
                error_exit "EPEL源安装失败,无法继续"
            }
        }
    fi
    
    # 对于CentOS 7,安装SCL源以获取较新的编译器
    if [ "$DISTRO" = "centos" ] && [ "$DISTRO_VERSION" -eq 7 ]; then
        if ! rpm -qa | grep -q "centos-release-scl"; then
            info "安装CentOS SCL软件源..."
            retry_command "$PKG_MANAGER install -y centos-release-scl" $RETRY_COUNT || {
                error_exit "SCL源安装失败,CentOS 7需要此源获取较新的编译器"
            }
        fi
    fi
    
    # 更新源缓存
    info "更新软件源缓存..."
    retry_command "$PKG_MANAGER clean all" $RETRY_COUNT
    retry_command "$PKG_MANAGER makecache fast" $RETRY_COUNT || {
        warn "缓存更新失败,尝试继续安装"
    }
    
    # 定义基础依赖包
    local base_deps=(
        # 基础编译工具
        gcc gcc-c++ make automake autoconf libtool pkgconfig
        # Python相关
        python3 python3-pip
        # 核心依赖
        glib2-devel expat-devel
        # 图像格式支持
        libjpeg-turbo-devel libpng-devel libtiff-devel libwebp-devel
        lcms2-devel poppler-glib-devel librsvg2-devel
        openjpeg2-devel fftw-devel pango-devel
        # 工具类
        wget curl tar xz unzip bzip2
    )
    
    # CentOS 7特殊依赖
    if [ "$DISTRO" = "centos" ] && [ "$DISTRO_VERSION" -eq 7 ]; then
        base_deps+=(
            devtoolset-9-gcc 
            devtoolset-9-gcc-c++
            devtoolset-9-binutils
        )
    fi
    
    # 宝塔环境特殊依赖
    if [ $BAOTA_ENV -eq 1 ]; then
        info "添加宝塔环境特殊依赖..."
        base_deps+=(
            zlib-devel openssl-devel
            libxml2-devel libxslt-devel
        )
    fi
    
    # 显示依赖数量
    info "需要安装的依赖包数量: ${#base_deps[@]}"
    
    # 安装依赖包
    info "开始安装依赖包..."
    if ! retry_command "$PKG_MANAGER install -y ${base_deps[@]}" $RETRY_COUNT; then
        warn "批量安装失败,尝试逐个安装依赖包..."
        local failed_deps=()
        
        for dep in "${base_deps[@]}"; do
            info "安装依赖: $dep"
            if ! retry_command "$PKG_MANAGER install -y $dep" 1; then
                warn "依赖包$dep安装失败,将记录并尝试继续"
                failed_deps+=("$dep")
            fi
        done
        
        # 检查关键依赖是否失败
        local critical_deps=("gcc" "glib2-devel" "make" "wget")
        for critical in "${critical_deps[@]}"; do
            if [[ " ${failed_deps[@]} " =~ " $critical " ]]; then
                error_exit "关键依赖包$critical安装失败,无法继续"
            fi
        done
        
        if [ ${#failed_deps[@]} -gt 0 ]; then
            warn "以下非关键依赖安装失败: ${failed_deps[*]}"
            warn "安装将继续,但可能影响部分功能"
        fi
    fi
}

# DEB系系统依赖安装 (Ubuntu/Debian)
install_deps_deb() {
    info "使用apt安装依赖包..."
    
    # 更新源
    info "更新apt源列表..."
    retry_command "apt update -y" $RETRY_COUNT || {
        info "尝试修复apt源问题..."
        retry_command "apt clean" $RETRY_COUNT
        retry_command "rm -rf /var/lib/apt/lists/*" $RETRY_COUNT
        retry_command "apt update -y" $RETRY_COUNT || {
            error_exit "apt源更新失败,无法继续"
        }
    }
    
    # 定义基础依赖包
    local base_deps=(
        # 基础编译工具
        gcc g++ make automake autoconf libtool pkg-config
        # Python相关
        python3 python3-pip
        # 核心依赖
        libglib2.0-dev libexpat1-dev
        # 图像格式支持
        libjpeg-dev libpng-dev libtiff-dev libwebp-dev
        liblcms2-dev libpoppler-glib-dev librsvg2-dev
        libopenjp2-7-dev libfftw3-dev libpango1.0-dev
        # 工具类
        wget curl tar xz-utils unzip bzip2
    )
    
    # 宝塔环境特殊依赖
    if [ $BAOTA_ENV -eq 1 ]; then
        info "添加宝塔环境特殊依赖..."
        base_deps+=(
            zlib1g-dev libssl-dev
            libxml2-dev libxslt1-dev
        )
    fi
    
    # 显示依赖数量
    info "需要安装的依赖包数量: ${#base_deps[@]}"
    
    # 安装依赖包
    info "开始安装依赖包..."
    if ! retry_command "apt install -y ${base_deps[@]}" $RETRY_COUNT; then
        warn "批量安装失败,尝试逐个安装依赖包..."
        local failed_deps=()
        
        for dep in "${base_deps[@]}"; do
            info "安装依赖: $dep"
            if ! retry_command "apt install -y $dep" 1; then
                warn "依赖包$dep安装失败,将记录并尝试继续"
                failed_deps+=("$dep")
            fi
        done
        
        # 检查关键依赖是否失败
        local critical_deps=("gcc" "libglib2.0-dev" "make" "wget")
        for critical in "${critical_deps[@]}"; do
            if [[ " ${failed_deps[@]} " =~ " $critical " ]]; then
                error_exit "关键依赖包$critical安装失败,无法继续"
            fi
        done
        
        if [ ${#failed_deps[@]} -gt 0 ]; then
            warn "以下非关键依赖安装失败: ${failed_deps[*]}"
            warn "安装将继续,但可能影响部分功能"
        fi
    fi
}

# ==============================================================
# 构建工具安装函数
# ==============================================================
install_build_tools() {
    show_title "安装构建工具"
    info "开始安装必要的构建工具..."
    
    # 安装/升级pip
    info "确保pip是最新版本..."
    if ! command -v pip3 &>/dev/null; then
        info "未找到pip3,尝试安装..."
        if [ "$PKG_MANAGER" = "apt" ]; then
            retry_command "apt install -y python3-pip" $RETRY_COUNT || error_exit "python3-pip安装失败"
        else
            retry_command "$PKG_MANAGER install -y python3-pip" $RETRY_COUNT || error_exit "python3-pip安装失败"
        fi
    fi
    
    retry_command "pip3 install --upgrade pip" $RETRY_COUNT || warn "pip升级失败,尝试继续"
    
    # 安装meson
    info "安装meson构建系统..."
    local required_meson_version="0.56"
    if ! command -v meson &>/dev/null; then
        info "未找到meson,开始安装..."
        retry_command "pip3 install meson==0.62.2" $RETRY_COUNT || error_exit "meson安装失败"
    else
        current_meson_version=$(meson --version | cut -d'.' -f1-2)
        info "当前meson版本: $current_meson_version,需要至少$required_meson_version"
        
        if (( $(echo "$current_meson_version < $required_meson_version" | bc -l) )); then
            info "meson版本过低,升级中..."
            retry_command "pip3 install --upgrade meson==0.62.2" $RETRY_COUNT || error_exit "meson升级失败"
        else
            info "meson版本符合要求"
        fi
    fi
    
    # 安装ninja
    info "安装ninja构建工具..."
    if ! command -v ninja &>/dev/null; then
        info "未找到ninja,开始安装..."
        local ninja_url="https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-linux.zip"
        local ninja_zip="${TMP_DIR}/ninja-linux.zip"
        
        retry_command "wget -q -O $ninja_zip $ninja_url" $RETRY_COUNT || error_exit "ninja下载失败"
        
        info "解压ninja..."
        unzip -q -o "$ninja_zip" -d "$TMP_DIR" || error_exit "ninja解压失败"
        
        info "安装ninja到系统目录..."
        cp "$TMP_DIR/ninja" "/usr/local/bin/" || error_exit "ninja复制失败"
        chmod +x "/usr/local/bin/ninja" || error_exit "ninja权限设置失败"
    else
        info "ninja已安装"
    fi
    
    # 验证构建工具
    info "验证构建工具安装..."
    if ! command -v meson &>/dev/null || ! command -v ninja &>/dev/null; then
        error_exit "构建工具安装不完整,无法继续"
    fi
    
    success "构建工具安装完成"
}

# ==============================================================
# 编译器配置函数
# ==============================================================
configure_compiler() {
    show_title "配置编译器环境"
    info "开始配置编译器环境..."
    
    # 检查GCC版本
    if ! command -v gcc &>/dev/null; then
        error_exit "未找到GCC编译器,无法继续"
    fi
    
    local gcc_version=$(gcc --version | head -n1 | awk '{print $4}' | cut -d'.' -f1)
    info "当前GCC版本: $gcc_version"
    
    # 对于CentOS 7,启用devtoolset-9
    if [ "$DISTRO" = "centos" ] && [ "$DISTRO_VERSION" -eq 7 ]; then
        info "CentOS 7系统,启用devtoolset-9..."
        if [ -f "/opt/rh/devtoolset-9/enable" ]; then
            # 临时启用
            source /opt/rh/devtoolset-9/enable || {
                error_exit "无法启用devtoolset-9,编译可能失败"
            }
            
            # 检查启用后的版本
            local new_gcc_version=$(gcc --version | head -n1 | awk '{print $4}' | cut -d'.' -f1)
            info "启用devtoolset-9后GCC版本: $new_gcc_version"
            
            if [ "$new_gcc_version" -lt 9 ]; then
                error_exit "启用devtoolset-9后GCC版本仍过低,需要至少9.0"
            fi
        else
            error_exit "未找到devtoolset-9,CentOS 7需要此工具包"
        fi
    else
        # 检查其他系统的GCC版本
        if [ "$gcc_version" -lt 5 ]; then
            error_exit "GCC版本过低,需要至少5.0版本,当前为$gcc_version"
        fi
    fi
    
    success "编译器环境配置完成"
}

# ==============================================================
# 源码下载与校验函数
# ==============================================================
download_and_verify_source() {
    show_title "下载并校验源码"
    info "开始下载libvips $VIPS_VERSION源码..."
    
    # 定义源码URL和校验和
    local source_url="https://github.com/libvips/libvips/releases/download/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.xz"
    local source_file="${TMP_DIR}/vips-${VIPS_VERSION}.tar.xz"
    local checksum_file="${TMP_DIR}/vips-${VIPS_VERSION}.tar.xz.sha256sum"
    local checksum_url="https://github.com/libvips/libvips/releases/download/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.xz.sha256sum"
    
    # 下载源码包
    info "源码下载地址: $source_url"
    info "开始下载源码包..."
    retry_command "wget -q -O $source_file $source_url" $RETRY_COUNT || {
        info "尝试使用curl重新下载..."
        retry_command "curl -s -o $source_file $source_url" $RETRY_COUNT || {
            error_exit "源码包下载失败,请检查网络连接"
        }
    }
    
    # 检查文件是否存在
    if [ ! -f "$source_file" ] || [ $(stat -c%s "$source_file") -eq 0 ]; then
        error_exit "源码包下载不完整或为空文件"
    fi
    
    # 下载校验和文件
    info "下载校验和文件..."
    retry_command "wget -q -O $checksum_file $checksum_url" $RETRY_COUNT || {
        warn "校验和文件下载失败,尝试从源码页面提取..."
        # 如果校验和文件下载失败,尝试从源码页面提取
        local checksum_page=$(wget -q -O - "https://github.com/libvips/libvips/releases/tag/v${VIPS_VERSION}")
        echo "$checksum_page" | grep -oE "[0-9a-fA-F]{64}.*vips-${VIPS_VERSION}\.tar\.xz" | head -n1 | awk '{print $1}' > "$checksum_file"
        
        if [ ! -s "$checksum_file" ]; then
            warn "无法获取校验和,将跳过校验步骤"
            return 0
        fi
    }
    
    # 校验文件完整性
    info "校验源码包完整性..."
    local expected_checksum=$(cat "$checksum_file" | awk '{print $1}')
    local actual_checksum=$(sha256sum "$source_file" | awk '{print $1}')
    
    if [ "$expected_checksum" != "$actual_checksum" ]; then
        error_exit "源码包校验失败: 预期$expected_checksum,实际$actual_checksum"
    fi
    
    success "源码下载与校验完成"
    echo "$source_file"
}

# ==============================================================
# 编译与安装函数
# ==============================================================
compile_and_install() {
    show_title "编译与安装libvips"
    info "开始编译与安装libvips $VIPS_VERSION..."
    
    # 解压源码
    local source_file="${TMP_DIR}/vips-${VIPS_VERSION}.tar.xz"
    info "解压源码包: $source_file"
    
    if ! tar xf "$source_file" -C "$TMP_DIR"; then
        error_exit "源码包解压失败"
    fi
    
    local source_dir="${TMP_DIR}/vips-${VIPS_VERSION}"
    if [ ! -d "$source_dir" ]; then
        error_exit "源码目录不存在: $source_dir"
    fi
    
    # 进入源码目录
    info "进入源码目录: $source_dir"
    cd "$source_dir" || error_exit "无法进入源码目录"
    
    # 创建构建目录
    local build_dir="${source_dir}/build"
    info "创建构建目录: $build_dir"
    mkdir -p "$build_dir" || error_exit "无法创建构建目录"
    
    # 配置构建选项
    info "配置libvips构建选项..."
    if ! meson setup "$build_dir" \
        --prefix="$BASE_DIR" \
        -Ddebug=false \
        -Ddeprecated=false \
        -Dexamples=false \
        -Dcplusplus=true \
        -Dintrospection=false; then
        
        error "meson配置失败,尝试清理后重新配置..."
        rm -rf "$build_dir"
        mkdir -p "$build_dir"
        
        # 详细输出配置过程以便调试
        if ! meson setup "$build_dir" \
            --prefix="$BASE_DIR" \
            -Ddebug=false \
            -Ddeprecated=false \
            -Dexamples=false \
            -Dcplusplus=true \
            -Dintrospection=false; then
            
            error_exit "meson配置彻底失败,请查看日志分析原因"
        fi
    fi
    
    # 编译源码
    info "开始编译源码 (使用$CPU_CORES个核心)..."
    if ! meson compile -C "$build_dir" -j"$CPU_CORES"; then
        warn "多核心编译失败,尝试单核心编译..."
        if ! meson compile -C "$build_dir" -j1; then
            error_exit "编译失败,请查看日志分析原因"
        fi
    fi
    
    # 安装编译结果
    info "开始安装libvips..."
    if ! meson install -C "$build_dir"; then
        error_exit "安装失败,请查看日志分析原因"
    fi
    
    success "libvips编译与安装完成"
}

# ==============================================================
# 系统配置函数
# ==============================================================
configure_system() {
    show_title "配置系统环境"
    info "开始配置系统环境..."
    
    # 更新动态链接库缓存
    info "更新动态链接库缓存..."
    if [ -f "/etc/ld.so.conf.d/libvips.conf" ]; then
        info "删除旧的libvips配置文件..."
        rm -f "/etc/ld.so.conf.d/libvips.conf"
    fi
    
    echo "${BASE_DIR}/lib" > "/etc/ld.so.conf.d/libvips.conf" || {
        warn "无法创建动态链接库配置文件,手动添加"
        echo "${BASE_DIR}/lib" >> "/etc/ld.so.conf"
    }
    
    ldconfig || warn "ldconfig执行失败,可能需要手动运行"
    
    # 配置环境变量
    info "配置环境变量..."
    local env_files=(
        "/etc/profile"
        "/etc/bashrc"
        "$HOME/.bashrc"
        "$HOME/.bash_profile"
    )
    
    for env_file in "${env_files[@]}"; do
        if [ -f "$env_file" ] && ! grep -q "${BASE_DIR}/bin" "$env_file"; then
            info "向$env_file添加环境变量..."
            echo "export PATH=\$PATH:${BASE_DIR}/bin" >> "$env_file"
        fi
    done
    
    # 立即生效环境变量
    export PATH="$PATH:${BASE_DIR}/bin"
    
    # 宝塔环境特殊配置
    if [ $BAOTA_ENV -eq 1 ]; then
        info "配置宝塔面板环境..."
        # 添加到宝塔的环境变量配置
        if [ -f "/www/server/panel/tools/set_path.sh" ]; then
            echo "${BASE_DIR}/bin" >> "/www/server/panel/tools/set_path.sh"
        fi
        
        # 重启宝塔面板服务
        info "重启宝塔面板服务..."
        /etc/init.d/bt restart >/dev/null 2>&1 || {
            systemctl restart bt >/dev/null 2>&1 || warn "宝塔面板重启失败,可能需要手动重启"
        }
    fi
    
    success "系统环境配置完成"
}

# ==============================================================
# 安装验证函数
# ==============================================================
verify_installation() {
    show_title "验证安装结果"
    info "开始验证libvips安装结果..."
    
    # 检查命令是否存在
    info "检查vips命令是否可用..."
    if ! command -v vips &>/dev/null; then
        warn "vips命令不在PATH中,尝试手动指定路径..."
        if [ -f "${BASE_DIR}/bin/vips" ]; then
            export PATH="${BASE_DIR}/bin:$PATH"
        else
            error_exit "未找到vips可执行文件,安装失败"
        fi
    fi
    
    # 检查版本
    info "检查安装版本..."
    local installed_version
    installed_version=$(vips --version | awk '{print $2}')
    
    if [ "$installed_version" != "$VIPS_VERSION" ]; then
        error_exit "版本不匹配: 预期$VIPS_VERSION,实际$installed_version"
    fi
    
    # 功能测试 - 创建测试图像
    info "测试基本功能 - 创建测试图像..."
    local test_image="${TMP_DIR}/test_vips_image.png"
    if ! vips black "$test_image" 200 200 >/dev/null 2>&1; then
        error_exit "创建测试图像失败,基本功能异常"
    fi
    
    # 功能测试 - 图像处理
    info "测试基本功能 - 图像处理..."
    local output_image="${TMP_DIR}/output_vips_image.png"
    if ! vips invert "$test_image" "$output_image" >/dev/null 2>&1; then
        error_exit "图像处理测试失败,功能异常"
    fi
    
    # 检查库文件
    info "检查库文件是否安装正确..."
    local lib_files=(
        "${BASE_DIR}/lib/libvips.so"
        "${BASE_DIR}/lib/libvips-cpp.so"
        "${BASE_DIR}/include/vips/vips.h"
    )
    
    for lib_file in "${lib_files[@]}"; do
        if [ ! -f "$lib_file" ]; then
            warn "库文件$lib_file不存在,可能影响部分功能"
        fi
    done
    
    success "安装验证通过,libvips $VIPS_VERSION 功能正常"
    SUCCESS=1
}

# ==============================================================
# 清理函数
# ==============================================================
clean_up() {
    show_title "清理临时文件"
    info "开始清理临时文件..."
    
    # 恢复防火墙状态
    if [ -n "$FIREWALLD_RUNNING" ]; then
        info "恢复firewalld状态..."
        systemctl start firewalld >/dev/null 2>&1 || warn "恢复firewalld失败"
    fi
    
    if [ -n "$IPTABLES_RUNNING" ]; then
        info "恢复iptables状态..."
        service iptables start >/dev/null 2>&1 || warn "恢复iptables失败"
    fi
    
    # 删除临时目录
    if [ -d "$TMP_DIR" ]; then
        info "删除临时目录: $TMP_DIR"
        rm -rf "$TMP_DIR" || warn "临时目录删除失败"
    fi
    
    success "清理工作完成"
}

# ==============================================================
# 辅助函数 - 带重试的命令执行
# ==============================================================
retry_command() {
    local command="$1"
    local max_attempts="$2"
    local attempt=1
    local delay=3
    
    while [ $attempt -le $max_attempts ]; do
        info "执行命令 (尝试 $attempt/$max_attempts): $command"
        
        # 执行命令并捕获输出
        if eval "$command" >/dev/null 2>&1; then
            return 0
        fi
        
        # 如果不是最后一次尝试,则等待后重试
        if [ $attempt -lt $max_attempts ]; then
            warn "命令执行失败,将在$delay秒后重试..."
            sleep $delay
            attempt=$((attempt + 1))
            delay=$((delay * 2)) # 指数退避
        else
            warn "命令执行失败,已达到最大重试次数"
            return 1
        fi
    done
    
    return 1
}

# ==============================================================
# 主函数
# ==============================================================
main() {
    # 显示欢迎信息
    clear
    show_title "libvips 一键安装工具 v2.0"
    info "欢迎使用libvips一键安装工具"
    info "本工具将自动安装libvips $VIPS_VERSION 到 $BASE_DIR"
    info "支持系统: CentOS/Ubuntu/Debian (含宝塔面板环境)"
    info "安装过程将自动进行,无需手动干预"
    info "详细日志将保存到: $LOG_FILE"
    echo -e "\n按任意键开始安装...\n"
    read -n 1 -s
    
    # 执行安装步骤
    detect_system          || error_exit "系统检测失败"
    system_prepare         || error_exit "系统预处理失败"
    install_dependencies   || error_exit "依赖安装失败"
    install_build_tools    || error_exit "构建工具安装失败"
    configure_compiler     || error_exit "编译器配置失败"
    download_and_verify_source || error_exit "源码下载与校验失败"
    compile_and_install    || error_exit "编译与安装失败"
    configure_system       || error_exit "系统配置失败"
    verify_installation    || error_exit "安装验证失败"
    clean_up               || warn "清理工作部分失败"
    
    # 显示安装成功信息
    show_title "安装完成"
    success "恭喜!libvips $VIPS_VERSION 已成功安装到 $BASE_DIR"
    success "安装路径: $BASE_DIR/bin/vips"
    success "版本信息: $(vips --version)"
    success "安装日志: $LOG_FILE"
    
    if [ $BAOTA_ENV -eq 1 ]; then
        success "宝塔面板环境已自动配置,可直接使用vips命令"
    fi
    
    success "安装总耗时: $(( $(date +%s) - $(stat -c %Y "$0") )) 秒"
    success "感谢使用本安装工具!"
}

# 启动主函数
main
THE END
点赞0
抢沙发
头像
提交
头像

昵称

取消
昵称图片快捷回复

    暂无评论内容