#!/usr/bin/env bash set -Eeuo pipefail REPO_ARCHIVE_URL="https://github.com/ghuang-top/AI_English/archive/refs/heads/main.tar.gz" TARGET_DIR="/root/data/docker_data/Nginx/html/english/ai" PRESERVED_NAME="data" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' print_info() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" >&2 } check_root() { if [[ ${EUID} -ne 0 ]]; then print_error "此脚本需要 root 权限运行" print_info "请切换到 root 用户,或使用 sudo bash 执行脚本" exit 1 fi } check_dependencies() { local command_name for command_name in curl tar find; do if ! command -v "$command_name" >/dev/null 2>&1; then print_error "缺少必要命令: $command_name" exit 1 fi done } prepare_target() { if [[ -e "$TARGET_DIR" && ! -d "$TARGET_DIR" ]]; then print_error "目标路径存在,但不是文件夹: $TARGET_DIR" exit 1 fi mkdir -p "$TARGET_DIR" } clear_target() { prepare_target print_info "正在清空目标目录(保留 $TARGET_DIR/$PRESERVED_NAME/)..." find "$TARGET_DIR" -mindepth 1 -maxdepth 1 ! -name "$PRESERVED_NAME" \ -exec rm -rf -- {} + print_success "目标目录已清空,$PRESERVED_NAME/ 中的内容未改动" } deploy() ( local temp_dir archive_file source_dir temp_dir=$(mktemp -d) archive_file="$temp_dir/repository.tar.gz" trap 'rm -rf -- "$temp_dir"' EXIT print_info "正在从 GitHub 下载最新版本..." if ! curl -fL --retry 3 --connect-timeout 15 "$REPO_ARCHIVE_URL" -o "$archive_file"; then print_error "仓库下载失败,请检查网络连接后重试" return 1 fi print_info "正在解压并验证部署文件..." if ! tar -xzf "$archive_file" -C "$temp_dir"; then print_error "仓库压缩包解压失败" return 1 fi source_dir=$(find "$temp_dir" -mindepth 2 -maxdepth 2 -type d -name src -print -quit) if [[ -z "$source_dir" || ! -f "$source_dir/index.html" || ! -d "$source_dir/js" || ! -d "$source_dir/styles" ]]; then print_error "仓库中缺少 src/index.html、src/js 或 src/styles,已取消部署" return 1 fi clear_target print_info "正在拷贝网站文件到 $TARGET_DIR ..." cp -a "$source_dir/index.html" "$source_dir/js" "$source_dir/styles" "$TARGET_DIR/" print_success "部署完成" print_info "已部署: index.html、js/、styles/" print_info "已保留: $TARGET_DIR/$PRESERVED_NAME/" ) confirm_clear() { local answer print_warning "将清空 $TARGET_DIR 中除 $PRESERVED_NAME/ 外的所有内容" read -r -p "确认继续?[y/N]: " answer if [[ "$answer" =~ ^[Yy]$ ]]; then clear_target else print_info "已取消清空" fi } show_menu() { clear 2>/dev/null || true echo -e "${CYAN}============================================${NC}" echo " AI English 一键部署脚本" echo -e "${CYAN}============================================${NC}" echo -e "${GREEN}1.${NC} 下载并部署最新版本" echo -e "${GREEN}2.${NC} 清空网站文件(保留 data/)" echo -e "${GREEN}0.${NC} 退出" echo "" } run_menu() { local choice while true; do show_menu read -r -p "请选择操作 [0-2]: " choice case "$choice" in 1) # 部署失败时回到菜单,而不是因 set -e 直接退出脚本 deploy || print_warning "部署失败,可稍后重试" read -r -p "按 Enter 键继续..." ;; 2) confirm_clear read -r -p "按 Enter 键继续..." ;; 0) print_info "退出脚本" return 0 ;; *) print_error "无效选择,请重新输入" sleep 1 ;; esac done } main() { check_root check_dependencies case "${1:-menu}" in deploy) deploy ;; clear) confirm_clear ;; menu) run_menu ;; *) print_error "未知参数: $1" echo "用法: $0 [deploy|clear|menu]" >&2 exit 1 ;; esac } main "$@"