v1.1.3: 集成卸载功能到主脚本

主要更新:
- 添加卸载模式: bash install.sh --uninstall
- 支持参数: --uninstall, -u, uninstall
- 双重确认机制防止误删
- 可选数据备份到 /root/wanwanyun-backup-*
- 完整清理: PM2进程、Nginx配置、SSL证书、项目目录
- 保留环境: Node.js、Nginx、PM2、编译工具
- 残留检查确保清理完整

使用方法:
- 安装: bash install.sh
- 卸载: bash install.sh --uninstall

功能特性:
- 智能备份询问
- 逐步状态显示
- 清理完成报告
- 环境保留列表
This commit is contained in:
WanWanYun
2025-11-10 23:48:32 +08:00
parent 8c7664a400
commit 9966719afa

View File

@@ -1,13 +1,18 @@
#!/bin/bash #!/bin/bash
################################################################################ ################################################################################
# 玩玩云 (WanWanYun) - 一键部署脚本 # 玩玩云 (WanWanYun) - 一键部署/卸载脚本
# 项目地址: https://gitee.com/yu-yon/vue-driven-cloud-storage # 项目地址: https://gitee.com/yu-yon/vue-driven-cloud-storage
# 版本: v1.1.2 # 版本: v1.1.3
################################################################################ ################################################################################
set -e set -e
# 检查运行模式
MODE="install"
if [[ "$1" == "--uninstall" ]] || [[ "$1" == "-u" ]] || [[ "$1" == "uninstall" ]]; then
MODE="uninstall"
fi
# 颜色定义 # 颜色定义
RED='\033[0;31m' RED='\033[0;31m'
@@ -1267,6 +1272,282 @@ print_completion() {
echo "" echo ""
} }
################################################################################
# 卸载功能
################################################################################
print_uninstall_banner() {
clear
echo -e "${RED}"
echo "╔═══════════════════════════════════════════════════════════════╗"
echo "║ ║"
echo "║ ⚠️ 玩玩云 卸载模式 ║"
echo "║ ║"
echo "║ Uninstall Mode ║"
echo "║ ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
}
confirm_uninstall() {
print_uninstall_banner
echo -e "${YELLOW}"
echo "本脚本将执行以下操作:"
echo ""
echo "【将要删除】"
echo " ✓ PM2 进程: ${PROJECT_NAME}-backend"
echo " ✓ 项目目录: ${PROJECT_DIR}"
echo " ✓ Nginx 配置: /etc/nginx/sites-enabled/${PROJECT_NAME}.conf"
echo " ✓ 数据库文件: ${PROJECT_DIR}/backend/data/"
echo " ✓ 用户文件: ${PROJECT_DIR}/backend/storage/"
echo ""
echo "【将会保留】"
echo " ✓ Node.js"
echo " ✓ Nginx (程序本身)"
echo " ✓ PM2 (程序本身)"
echo " ✓ 编译工具 (build-essential等)"
echo -e "${NC}"
echo ""
print_warning "此操作不可逆,所有数据将被永久删除!"
echo ""
read -p "确定要卸载吗? (yes/no): " confirm < /dev/tty
if [[ "$confirm" != "yes" ]]; then
print_info "已取消卸载"
exit 0
fi
echo ""
read -p "请再次确认 (yes/no): " confirm2 < /dev/tty
if [[ "$confirm2" != "yes" ]]; then
print_info "已取消卸载"
exit 0
fi
echo ""
}
uninstall_backup_data() {
print_step "备份用户数据..."
if [[ ! -d "$PROJECT_DIR" ]]; then
print_info "项目目录不存在,跳过备份"
return
fi
BACKUP_DIR="/root/${PROJECT_NAME}-backup-$(date +%Y%m%d-%H%M%S)"
echo ""
read -p "是否备份用户数据? (y/n): " backup_choice < /dev/tty
if [[ "$backup_choice" == "y" || "$backup_choice" == "Y" ]]; then
mkdir -p "$BACKUP_DIR"
# 备份数据库
if [[ -d "${PROJECT_DIR}/backend/data" ]]; then
cp -r "${PROJECT_DIR}/backend/data" "$BACKUP_DIR/"
print_success "数据库已备份"
fi
# 备份用户文件
if [[ -d "${PROJECT_DIR}/backend/storage" ]]; then
cp -r "${PROJECT_DIR}/backend/storage" "$BACKUP_DIR/"
print_success "用户文件已备份"
fi
# 备份配置文件
if [[ -f "${PROJECT_DIR}/backend/.env" ]]; then
cp "${PROJECT_DIR}/backend/.env" "$BACKUP_DIR/"
print_success "配置文件已备份"
fi
print_success "备份已保存到: $BACKUP_DIR"
echo ""
else
print_warning "跳过备份,数据将被永久删除"
echo ""
fi
}
uninstall_stop_pm2() {
print_step "停止PM2进程..."
if command -v pm2 &> /dev/null; then
if pm2 list | grep -q "${PROJECT_NAME}-backend"; then
pm2 delete ${PROJECT_NAME}-backend
pm2 save --force
print_success "PM2进程已停止并删除"
else
print_info "PM2进程不存在跳过"
fi
else
print_info "PM2未安装跳过"
fi
}
uninstall_nginx_config() {
print_step "删除Nginx配置..."
local need_reload=false
# 删除sites-enabled软链接
if [[ -L /etc/nginx/sites-enabled/${PROJECT_NAME}.conf ]]; then
rm -f /etc/nginx/sites-enabled/${PROJECT_NAME}.conf
print_success "删除 sites-enabled 配置"
need_reload=true
fi
# 删除sites-available配置文件
if [[ -f /etc/nginx/sites-available/${PROJECT_NAME}.conf ]]; then
rm -f /etc/nginx/sites-available/${PROJECT_NAME}.conf
print_success "删除 sites-available 配置"
fi
# 测试并重载nginx
if [[ "$need_reload" == true ]] && command -v nginx &> /dev/null; then
if nginx -t &> /dev/null; then
systemctl reload nginx
print_success "Nginx配置已重载"
else
print_warning "Nginx配置测试失败请手动检查"
fi
fi
}
uninstall_ssl_certificates() {
print_step "清理SSL证书..."
# 删除nginx SSL证书目录下的项目证书
local cert_removed=false
if [[ -d /etc/nginx/ssl ]]; then
# 使用find查找包含项目名或域名的证书
find /etc/nginx/ssl -name "*${PROJECT_NAME}*" -type f -delete 2>/dev/null && cert_removed=true
fi
if [[ "$cert_removed" == true ]]; then
print_success "已删除Nginx SSL证书"
else
print_info "未发现Nginx SSL证书"
fi
# 提示acme.sh证书
if [[ -d ~/.acme.sh ]]; then
if ~/.acme.sh/acme.sh --list 2>/dev/null | grep -q "Main_Domain"; then
print_info "检测到acme.sh证书"
print_warning "如需删除,请手动运行: ~/.acme.sh/acme.sh --remove -d <your-domain>"
fi
fi
}
uninstall_project_directory() {
print_step "删除项目目录..."
if [[ -d "$PROJECT_DIR" ]]; then
# 统计大小
SIZE=$(du -sh "$PROJECT_DIR" 2>/dev/null | cut -f1 || echo "未知")
print_info "项目目录大小: $SIZE"
# 删除目录
rm -rf "$PROJECT_DIR"
print_success "项目目录已删除: $PROJECT_DIR"
else
print_info "项目目录不存在: $PROJECT_DIR"
fi
}
uninstall_temp_files() {
print_step "清理临时文件..."
local cleaned=false
# 清理/tmp下的临时文件
if [[ -d "/tmp/${PROJECT_NAME}" ]]; then
rm -rf "/tmp/${PROJECT_NAME}"
print_success "删除临时目录"
cleaned=true
fi
# 清理npm缓存
if command -v npm &> /dev/null; then
npm cache clean --force &> /dev/null || true
print_success "清理npm缓存"
cleaned=true
fi
if [[ "$cleaned" == false ]]; then
print_info "无需清理"
fi
}
uninstall_check_residual() {
print_step "检查残留文件..."
local residual_found=false
# 检查项目目录
if [[ -d "$PROJECT_DIR" ]]; then
print_warning "残留: 项目目录 $PROJECT_DIR"
residual_found=true
fi
# 检查Nginx配置
if [[ -f /etc/nginx/sites-enabled/${PROJECT_NAME}.conf ]] || [[ -f /etc/nginx/sites-available/${PROJECT_NAME}.conf ]]; then
print_warning "残留: Nginx配置文件"
residual_found=true
fi
# 检查PM2进程
if command -v pm2 &> /dev/null; then
if pm2 list | grep -q "${PROJECT_NAME}"; then
print_warning "残留: PM2进程"
residual_found=true
fi
fi
if [[ "$residual_found" == false ]]; then
print_success "未发现残留文件"
fi
}
print_uninstall_completion() {
clear
echo -e "${GREEN}"
echo "╔═══════════════════════════════════════════════════════════════╗"
echo "║ ║"
echo "║ ✓ 卸载完成! ║"
echo "║ ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
echo ""
echo -e "${CYAN}已删除内容:${NC}"
echo " ✓ PM2进程"
echo " ✓ 项目目录"
echo " ✓ Nginx配置"
echo " ✓ 数据库和用户文件"
echo ""
echo -e "${CYAN}保留的环境:${NC}"
echo " ✓ Node.js $(node -v 2>/dev/null || echo '(未安装)')"
echo " ✓ Nginx $(nginx -v 2>&1 | cut -d'/' -f2 || echo '(未安装)')"
echo " ✓ PM2 $(pm2 -v 2>/dev/null || echo '(未安装)')"
echo " ✓ 编译工具 (build-essential 等)"
echo ""
if [[ -n "$BACKUP_DIR" ]] && [[ -d "$BACKUP_DIR" ]]; then
echo -e "${YELLOW}备份位置:${NC}"
echo " $BACKUP_DIR"
echo ""
fi
echo -e "${GREEN}感谢使用玩玩云!${NC}"
echo ""
}
################################################################################ ################################################################################
# 主流程 # 主流程
################################################################################ ################################################################################
@@ -1326,5 +1607,41 @@ main() {
print_completion print_completion
} }
uninstall_main() {
# 检查root权限
check_root
# 确认卸载
confirm_uninstall
# 备份数据
uninstall_backup_data
# 停止PM2进程
uninstall_stop_pm2
# 删除Nginx配置
uninstall_nginx_config
# 清理SSL证书
uninstall_ssl_certificates
# 删除项目目录
uninstall_project_directory
# 清理临时文件
uninstall_temp_files
# 检查残留
uninstall_check_residual
# 完成提示
print_uninstall_completion
}
# 执行主流程 # 执行主流程
main if [[ "$MODE" == "uninstall" ]]; then
uninstall_main
else
main
fi