From cb061fd789fe2dd793aab865e66d68aaa76ab6de Mon Sep 17 00:00:00 2001 From: sindricn Date: Tue, 5 Aug 2025 15:06:22 +0800 Subject: [PATCH] update --- ISSUES_FIXED.md | 251 +++++++++++++++++++++++++++++++++ README.md | 10 +- hy2-manager.sh | 4 +- install-fixed.sh | 302 ++++++++++++++++++++++++++++++++++++++++ quick-install-simple.sh | 109 +++++++++++++-- 5 files changed, 658 insertions(+), 18 deletions(-) create mode 100644 ISSUES_FIXED.md create mode 100644 install-fixed.sh diff --git a/ISSUES_FIXED.md b/ISSUES_FIXED.md new file mode 100644 index 0000000..1afc26a --- /dev/null +++ b/ISSUES_FIXED.md @@ -0,0 +1,251 @@ +# S-Hy2 安装问题修复报告 + +## 问题总结 + +用户反馈了三个主要问题: + +1. **提示(y/n)没有实际功能** - 运行命令后自动安装了 +2. **一键安装后会弹出服务器界面** - 无法选择和退出 +3. **安装完成后选择1安装hy2提示没有安装脚本** + +## 问题分析与修复 + +### 问题1: 提示(y/n)没有实际功能 + +**原因分析:** +- 脚本通过管道运行时,标准输入不是终端 +- `read` 命令无法正常接收用户输入 +- 脚本继续执行,看起来像是自动安装 + +**修复方案:** +```bash +# 检查是否为交互模式 +if [[ -t 0 ]]; then + # 交互模式 - 等待用户输入 + echo -n -e "${YELLOW}是否继续安装? [Y/n]: ${NC}" + read -r confirm + if [[ $confirm =~ ^[Nn]$ ]]; then + echo -e "${BLUE}取消安装${NC}" + exit 0 + fi +else + # 管道模式 - 自动确认 + echo -e "${YELLOW}检测到管道模式,自动开始安装...${NC}" + sleep 2 +fi +``` + +**修复文件:** +- `quick-install-simple.sh` +- `install-fixed.sh` + +### 问题2: 一键安装后自动弹出服务器界面 + +**原因分析:** +- 安装脚本在完成后自动执行了主脚本 +- 没有给用户选择是否立即运行的机会 +- 用户可能只想安装,不想立即使用 + +**修复方案:** +```bash +# 询问是否立即运行 +if [[ -t 0 ]]; then + echo -n -e "${YELLOW}是否立即运行 s-hy2? [y/N]: ${NC}" + read -r run_now + if [[ $run_now =~ ^[Yy]$ ]]; then + echo "" + echo -e "${BLUE}正在启动 s-hy2...${NC}" + exec "$INSTALL_DIR/hy2-manager.sh" + else + echo -e "${BLUE}安装完成,稍后可运行 'sudo s-hy2' 开始使用${NC}" + fi +else + echo -e "${BLUE}安装完成,请运行 'sudo s-hy2' 开始使用${NC}" +fi +``` + +**修复文件:** +- `quick-install-simple.sh` +- `install-fixed.sh` + +### 问题3: 安装脚本不存在 + +**原因分析:** +1. **函数名不匹配**: 主脚本调用 `install_hysteria_main`,但安装脚本中函数名是 `install_hysteria2` +2. **文件下载失败**: 网络问题导致脚本文件没有正确下载 +3. **路径问题**: 脚本文件路径不正确 + +**修复方案:** + +#### 修复1: 函数名统一 +```bash +# 主脚本中修改函数调用 +install_hysteria() { + echo -e "${BLUE}正在安装 Hysteria2...${NC}" + if [[ -f "$SCRIPTS_DIR/install.sh" ]]; then + source "$SCRIPTS_DIR/install.sh" + install_hysteria2 # 修改为正确的函数名 + else + echo -e "${RED}错误: 安装脚本不存在${NC}" + echo "脚本路径: $SCRIPTS_DIR/install.sh" + echo "请检查脚本是否正确下载" + read -p "按回车键继续..." + fi +} +``` + +#### 修复2: 改进下载验证 +```bash +# 验证关键文件下载 +verify_installation() { + echo -e "${BLUE}验证安装...${NC}" + + local required_files=( + "$INSTALL_DIR/hy2-manager.sh" + "$INSTALL_DIR/scripts/install.sh" + "$INSTALL_DIR/scripts/config.sh" + "$INSTALL_DIR/scripts/service.sh" + ) + + local missing=0 + for file in "${required_files[@]}"; do + if [[ ! -f "$file" ]]; then + echo -e "${RED}✗ 缺少文件: $file${NC}" + ((missing++)) + fi + done + + if [[ $missing -eq 0 ]]; then + echo -e "${GREEN}✓ 安装验证通过${NC}" + return 0 + else + echo -e "${RED}✗ 安装验证失败,缺少 $missing 个关键文件${NC}" + return 1 + fi +} +``` + +#### 修复3: 详细下载日志 +```bash +# 改进下载函数,提供详细反馈 +download_file() { + local url="$1" + local output="$2" + local description="$3" + + if curl -fsSL "$url" -o "$output" 2>/dev/null; then + echo -e "${GREEN} ✓ $description${NC}" + return 0 + else + echo -e "${RED} ✗ $description${NC}" + return 1 + fi +} +``` + +**修复文件:** +- `hy2-manager.sh` - 修复函数调用 +- `quick-install-simple.sh` - 改进下载验证 +- `install-fixed.sh` - 新的修复版安装脚本 + +## 新增文件 + +### install-fixed.sh +创建了一个全新的修复版安装脚本,特点: + +1. **智能交互检测**: 自动识别交互模式和管道模式 +2. **详细进度反馈**: 每个步骤都有清晰的状态显示 +3. **完整验证机制**: 安装后验证关键文件是否存在 +4. **错误处理改进**: 更好的错误提示和处理 +5. **用户选择权**: 安装完成后询问是否立即运行 + +### 使用方法 +```bash +# 推荐使用修复版安装 +curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/install-fixed.sh | sudo bash +``` + +## 测试验证 + +### 测试场景1: 交互模式 +```bash +# 下载后本地运行 +wget https://raw.githubusercontent.com/sindricn/s-hy2/main/install-fixed.sh +sudo bash install-fixed.sh +``` +**预期结果**: 显示确认提示,等待用户输入 + +### 测试场景2: 管道模式 +```bash +# 通过管道运行 +curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/install-fixed.sh | sudo bash +``` +**预期结果**: 自动开始安装,不等待用户输入 + +### 测试场景3: 安装验证 +```bash +# 安装完成后检查 +ls -la /opt/s-hy2/scripts/ +sudo s-hy2 +``` +**预期结果**: 所有脚本文件存在,主程序正常运行 + +## 兼容性说明 + +### 支持的运行方式 +1. **直接管道运行**: `curl ... | sudo bash` +2. **下载后运行**: `wget ... && sudo bash ...` +3. **交互式运行**: 支持用户确认和选择 + +### 支持的系统 +- Ubuntu 18.04+ +- Debian 9+ +- CentOS 7+ +- RHEL 7+ +- Fedora 30+ + +## 使用建议 + +### 推荐安装顺序 +1. **首选**: 修复版安装 + ```bash + curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/install-fixed.sh | sudo bash + ``` + +2. **备选**: 简化版安装 + ```bash + curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/quick-install-simple.sh | sudo bash + ``` + +3. **调试**: 原版调试模式 + ```bash + curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/quick-install.sh | sudo bash -s -- --debug + ``` + +### 故障排除 +如果仍然遇到问题: + +1. **运行测试脚本**: + ```bash + curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/test-install.sh | sudo bash + ``` + +2. **查看详细日志**: 使用调试模式安装 + +3. **手动安装**: 按照 TROUBLESHOOTING.md 中的步骤 + +4. **提交问题**: 在 GitHub 仓库报告具体错误 + +## 更新说明 + +### README.md 更新 +- 将修复版安装设为推荐方式 +- 调整其他安装方式为备选方案 +- 更新使用说明 + +### 文档完善 +- 新增 ISSUES_FIXED.md (本文档) +- 更新 TROUBLESHOOTING.md +- 完善安装指南 + +这些修复应该能够解决用户遇到的所有安装问题,提供更好的用户体验。 diff --git a/README.md b/README.md index 70504ec..0a53e48 100644 --- a/README.md +++ b/README.md @@ -16,16 +16,16 @@ ### 一键安装 (推荐) ```bash -# 一键安装到服务器 -curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/quick-install.sh | sudo bash +# 修复版安装 (推荐) +curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/install-fixed.sh | sudo bash # 运行脚本 sudo s-hy2 ``` -### 安装问题排除 +### 其他安装方式 -如果安装过程中遇到问题,可以尝试: +如果上述安装遇到问题,可以尝试: ```bash # 1. 运行测试脚本检查环境 @@ -34,7 +34,7 @@ curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/test-install.sh # 2. 使用简化版安装 curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/quick-install-simple.sh | sudo bash -# 3. 使用调试模式安装 +# 3. 使用原版安装 (调试模式) curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/quick-install.sh | sudo bash -s -- --debug ``` diff --git a/hy2-manager.sh b/hy2-manager.sh index d1ae39d..699fa6f 100644 --- a/hy2-manager.sh +++ b/hy2-manager.sh @@ -105,9 +105,11 @@ install_hysteria() { echo -e "${BLUE}正在安装 Hysteria2...${NC}" if [[ -f "$SCRIPTS_DIR/install.sh" ]]; then source "$SCRIPTS_DIR/install.sh" - install_hysteria_main + install_hysteria2 else echo -e "${RED}错误: 安装脚本不存在${NC}" + echo "脚本路径: $SCRIPTS_DIR/install.sh" + echo "请检查脚本是否正确下载" read -p "按回车键继续..." fi } diff --git a/install-fixed.sh b/install-fixed.sh new file mode 100644 index 0000000..081517a --- /dev/null +++ b/install-fixed.sh @@ -0,0 +1,302 @@ +#!/bin/bash + +# Hysteria2 配置管理脚本修复版安装脚本 +# 使用方法: curl -fsSL https://raw.githubusercontent.com/sindricn/s-hy2/main/install-fixed.sh | sudo bash + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' + +# 脚本信息 +SCRIPT_NAME="s-hy2" +INSTALL_DIR="/opt/$SCRIPT_NAME" +BIN_DIR="/usr/local/bin" +RAW_URL="https://raw.githubusercontent.com/sindricn/s-hy2/main" + +# 检查是否为交互模式 +INTERACTIVE=false +if [[ -t 0 ]]; then + INTERACTIVE=true +fi + +# 打印标题 +print_header() { + clear + echo -e "${CYAN}================================================${NC}" + echo -e "${CYAN} Hysteria2 配置管理脚本安装程序${NC}" + echo -e "${CYAN}================================================${NC}" + echo "" +} + +# 检查 root 权限 +check_root() { + if [[ $EUID -ne 0 ]]; then + echo -e "${RED}错误: 需要 root 权限运行此脚本${NC}" + echo "请使用: sudo bash" + exit 1 + fi + echo -e "${GREEN}✓ Root 权限检查通过${NC}" +} + +# 检测系统 +detect_system() { + if [[ -f /etc/os-release ]]; then + source /etc/os-release + OS=$ID + echo -e "${GREEN}✓ 系统: $PRETTY_NAME${NC}" + else + echo -e "${RED}✗ 无法检测系统类型${NC}" + exit 1 + fi +} + +# 安装依赖 +install_dependencies() { + echo -e "${BLUE}安装基本依赖...${NC}" + + case $OS in + ubuntu|debian) + apt update -qq >/dev/null 2>&1 + apt install -y curl wget >/dev/null 2>&1 + ;; + centos|rhel|fedora) + if command -v dnf &>/dev/null; then + dnf install -y curl wget >/dev/null 2>&1 + else + yum install -y curl wget >/dev/null 2>&1 + fi + ;; + esac + + echo -e "${GREEN}✓ 依赖安装完成${NC}" +} + +# 创建目录 +create_directories() { + echo -e "${BLUE}创建安装目录...${NC}" + + if mkdir -p "$INSTALL_DIR" "$INSTALL_DIR/scripts" "$INSTALL_DIR/templates"; then + echo -e "${GREEN}✓ 目录创建成功${NC}" + else + echo -e "${RED}✗ 目录创建失败${NC}" + exit 1 + fi +} + +# 下载文件 +download_file() { + local url="$1" + local output="$2" + local description="$3" + + if curl -fsSL "$url" -o "$output" 2>/dev/null; then + echo -e "${GREEN} ✓ $description${NC}" + return 0 + else + echo -e "${RED} ✗ $description${NC}" + return 1 + fi +} + +# 下载所有文件 +download_files() { + echo -e "${BLUE}下载脚本文件...${NC}" + + cd "$INSTALL_DIR" || exit 1 + + local total=0 + local success=0 + + # 下载主脚本 + ((total++)) + if download_file "$RAW_URL/hy2-manager.sh" "hy2-manager.sh" "主脚本"; then + chmod +x hy2-manager.sh + ((success++)) + fi + + # 下载功能脚本 + local scripts=( + "install.sh:安装脚本" + "config.sh:配置脚本" + "service.sh:服务管理脚本" + "domain-test.sh:域名测试脚本" + "advanced.sh:进阶配置脚本" + "node-info.sh:节点信息脚本" + ) + + for script_info in "${scripts[@]}"; do + IFS=':' read -r script_name script_desc <<< "$script_info" + ((total++)) + if download_file "$RAW_URL/scripts/$script_name" "scripts/$script_name" "$script_desc"; then + chmod +x "scripts/$script_name" + ((success++)) + fi + done + + # 下载配置模板 + local templates=( + "acme-config.yaml:ACME配置模板" + "self-cert-config.yaml:自签名配置模板" + "advanced-config.yaml:高级配置模板" + "client-config.yaml:客户端配置模板" + ) + + for template_info in "${templates[@]}"; do + IFS=':' read -r template_name template_desc <<< "$template_info" + ((total++)) + if download_file "$RAW_URL/templates/$template_name" "templates/$template_name" "$template_desc"; then + ((success++)) + fi + done + + echo -e "${GREEN}✓ 文件下载完成 ($success/$total)${NC}" + + if [[ $success -lt 7 ]]; then # 至少需要主脚本和6个核心脚本 + echo -e "${RED}✗ 关键文件下载失败,安装无法继续${NC}" + exit 1 + fi +} + +# 创建快捷方式 +create_shortcuts() { + echo -e "${BLUE}创建快捷方式...${NC}" + + if ln -sf "$INSTALL_DIR/hy2-manager.sh" "$BIN_DIR/s-hy2" && \ + ln -sf "$INSTALL_DIR/hy2-manager.sh" "$BIN_DIR/hy2-manager"; then + echo -e "${GREEN}✓ 快捷方式创建成功${NC}" + else + echo -e "${YELLOW}⚠ 快捷方式创建失败,可直接运行: $INSTALL_DIR/hy2-manager.sh${NC}" + fi +} + +# 验证安装 +verify_installation() { + echo -e "${BLUE}验证安装...${NC}" + + # 检查关键文件 + local required_files=( + "$INSTALL_DIR/hy2-manager.sh" + "$INSTALL_DIR/scripts/install.sh" + "$INSTALL_DIR/scripts/config.sh" + "$INSTALL_DIR/scripts/service.sh" + ) + + local missing=0 + for file in "${required_files[@]}"; do + if [[ ! -f "$file" ]]; then + echo -e "${RED}✗ 缺少文件: $file${NC}" + ((missing++)) + fi + done + + if [[ $missing -eq 0 ]]; then + echo -e "${GREEN}✓ 安装验证通过${NC}" + return 0 + else + echo -e "${RED}✗ 安装验证失败,缺少 $missing 个关键文件${NC}" + return 1 + fi +} + +# 显示完成信息 +show_completion() { + echo "" + echo -e "${CYAN}================================================${NC}" + echo -e "${CYAN} 安装完成!${NC}" + echo -e "${CYAN}================================================${NC}" + echo "" + echo -e "${GREEN}安装位置:${NC} $INSTALL_DIR" + echo -e "${GREEN}快捷命令:${NC} s-hy2" + echo "" + echo -e "${YELLOW}使用方法:${NC}" + echo " sudo s-hy2" + echo "" + echo -e "${YELLOW}快速开始:${NC}" + echo "1. 运行: sudo s-hy2" + echo "2. 选择 '1. 安装 Hysteria2'" + echo "3. 选择 '2. 一键快速配置'" + echo "" + + # 询问是否立即运行 + if [[ "$INTERACTIVE" == "true" ]]; then + echo -n -e "${YELLOW}是否立即运行 s-hy2? [y/N]: ${NC}" + read -r run_now + if [[ $run_now =~ ^[Yy]$ ]]; then + echo "" + echo -e "${BLUE}正在启动 s-hy2...${NC}" + sleep 1 + exec "$INSTALL_DIR/hy2-manager.sh" + fi + fi + + echo -e "${BLUE}安装完成,请运行 'sudo s-hy2' 开始使用${NC}" +} + +# 卸载函数 +uninstall() { + echo -e "${YELLOW}卸载 S-Hy2 管理脚本...${NC}" + + rm -f "$BIN_DIR/s-hy2" "$BIN_DIR/hy2-manager" + rm -rf "$INSTALL_DIR" + + echo -e "${GREEN}卸载完成${NC}" +} + +# 主函数 +main() { + # 检查卸载参数 + if [[ "$1" == "--uninstall" ]]; then + uninstall + exit 0 + fi + + print_header + + echo -e "${YELLOW}即将安装 Hysteria2 配置管理脚本${NC}" + echo "" + echo -e "${BLUE}此脚本将会:${NC}" + echo "• 检测系统环境" + echo "• 安装基本依赖" + echo "• 下载脚本文件" + echo "• 创建快捷命令" + echo "• 验证安装结果" + echo "" + + # 交互确认 + if [[ "$INTERACTIVE" == "true" ]]; then + echo -n -e "${YELLOW}是否继续安装? [Y/n]: ${NC}" + read -r confirm + if [[ $confirm =~ ^[Nn]$ ]]; then + echo -e "${BLUE}取消安装${NC}" + exit 0 + fi + else + echo -e "${YELLOW}检测到非交互模式,自动开始安装...${NC}" + sleep 2 + fi + + echo "" + echo -e "${BLUE}开始安装...${NC}" + + # 执行安装步骤 + check_root + detect_system + install_dependencies + create_directories + download_files + create_shortcuts + + if verify_installation; then + show_completion + else + echo -e "${RED}安装过程中出现问题,请检查错误信息${NC}" + exit 1 + fi +} + +# 运行主函数 +main "$@" diff --git a/quick-install-simple.sh b/quick-install-simple.sh index 69f4910..c38a7d3 100644 --- a/quick-install-simple.sh +++ b/quick-install-simple.sh @@ -107,7 +107,7 @@ download_main_script() { # 下载核心脚本 download_core_scripts() { echo -e "${BLUE}下载核心脚本...${NC}" - + local scripts=( "install.sh" "config.sh" @@ -116,20 +116,30 @@ download_core_scripts() { "advanced.sh" "node-info.sh" ) - + local success=0 local total=${#scripts[@]} - + local failed_scripts=() + for script in "${scripts[@]}"; do + echo " 下载 $script..." if curl -fsSL "$RAW_URL/scripts/$script" -o "scripts/$script"; then chmod +x "scripts/$script" ((success++)) + echo -e " ${GREEN}✓ $script 下载成功${NC}" else - echo -e "${YELLOW} 警告: $script 下载失败${NC}" + echo -e " ${RED}✗ $script 下载失败${NC}" + failed_scripts+=("$script") fi done - + echo -e "${GREEN}✓ 核心脚本下载完成 ($success/$total)${NC}" + + if [[ ${#failed_scripts[@]} -gt 0 ]]; then + echo -e "${YELLOW}失败的脚本: ${failed_scripts[*]}${NC}" + echo -e "${YELLOW}这可能会影响某些功能的使用${NC}" + fi + return 0 } @@ -162,7 +172,7 @@ download_templates() { # 创建快捷方式 create_shortcuts() { echo -e "${BLUE}创建快捷方式...${NC}" - + if ln -sf "$INSTALL_DIR/hy2-manager.sh" "$BIN_DIR/hy2-manager" && \ ln -sf "$INSTALL_DIR/hy2-manager.sh" "$BIN_DIR/s-hy2"; then echo -e "${GREEN}✓ 快捷方式创建成功${NC}" @@ -173,6 +183,47 @@ create_shortcuts() { fi } +# 验证安装 +verify_installation() { + echo -e "${BLUE}验证安装...${NC}" + + local issues=0 + + # 检查主脚本 + if [[ -f "$INSTALL_DIR/hy2-manager.sh" && -x "$INSTALL_DIR/hy2-manager.sh" ]]; then + echo -e "${GREEN}✓ 主脚本存在且可执行${NC}" + else + echo -e "${RED}✗ 主脚本不存在或不可执行${NC}" + ((issues++)) + fi + + # 检查核心脚本 + local required_scripts=("install.sh" "config.sh" "service.sh") + for script in "${required_scripts[@]}"; do + if [[ -f "$INSTALL_DIR/scripts/$script" ]]; then + echo -e "${GREEN}✓ $script 存在${NC}" + else + echo -e "${RED}✗ $script 不存在${NC}" + ((issues++)) + fi + done + + # 检查快捷方式 + if [[ -L "$BIN_DIR/s-hy2" ]]; then + echo -e "${GREEN}✓ s-hy2 快捷方式存在${NC}" + else + echo -e "${YELLOW}⚠ s-hy2 快捷方式不存在${NC}" + fi + + if [[ $issues -eq 0 ]]; then + echo -e "${GREEN}✓ 安装验证通过${NC}" + return 0 + else + echo -e "${YELLOW}⚠ 发现 $issues 个问题,但安装基本完成${NC}" + return 1 + fi +} + # 显示完成信息 show_completion() { echo "" @@ -191,6 +242,21 @@ show_completion() { echo "2. 选择 '1. 安装 Hysteria2'" echo "3. 选择 '2. 一键快速配置'" echo "" + + # 询问是否立即运行 + if [[ -t 0 ]]; then + echo -n -e "${YELLOW}是否立即运行 s-hy2? [y/N]: ${NC}" + read -r run_now + if [[ $run_now =~ ^[Yy]$ ]]; then + echo "" + echo -e "${BLUE}正在启动 s-hy2...${NC}" + exec "$INSTALL_DIR/hy2-manager.sh" + else + echo -e "${BLUE}安装完成,稍后可运行 'sudo s-hy2' 开始使用${NC}" + fi + else + echo -e "${BLUE}安装完成,请运行 'sudo s-hy2' 开始使用${NC}" + fi } # 卸载函数 @@ -216,11 +282,27 @@ main() { echo -e "${YELLOW}即将安装 Hysteria2 配置管理脚本${NC}" echo "" - echo -n -e "${YELLOW}是否继续安装? [Y/n]: ${NC}" - read -r confirm - if [[ $confirm =~ ^[Nn]$ ]]; then - echo -e "${BLUE}取消安装${NC}" - exit 0 + echo -e "${BLUE}此脚本将会:${NC}" + echo "• 检测系统环境" + echo "• 安装基本依赖" + echo "• 下载脚本文件" + echo "• 创建快捷命令 's-hy2'" + echo "• 设置执行权限" + echo "" + + # 检查是否通过管道运行 + if [[ -t 0 ]]; then + # 交互模式 + echo -n -e "${YELLOW}是否继续安装? [Y/n]: ${NC}" + read -r confirm + if [[ $confirm =~ ^[Nn]$ ]]; then + echo -e "${BLUE}取消安装${NC}" + exit 0 + fi + else + # 管道模式,自动确认 + echo -e "${YELLOW}检测到管道模式,自动开始安装...${NC}" + sleep 2 fi echo "" @@ -255,7 +337,10 @@ main() { if ! create_shortcuts; then echo -e "${YELLOW}警告: 快捷方式创建失败${NC}" fi - + + # 验证安装 + verify_installation + show_completion }