#!/bin/bash # ============================================ # LinkMaster 节点端一键卸载脚本 # 使用方法: curl -fsSL https://gitee.nas.cpolar.cn/yoyo/linkmaster-node/raw/branch/main/uninstall.sh | bash # 或: ./uninstall.sh # ============================================ set -e # 颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # 配置 BINARY_NAME="linkmaster-node" INSTALL_DIR="/usr/local/bin" SERVICE_NAME="linkmaster-node" SOURCE_DIR="/opt/linkmaster-node" CONFIG_FILE="${SOURCE_DIR}/config.yaml" LOG_FILE="${SOURCE_DIR}/node.log" PID_FILE="${SOURCE_DIR}/node.pid" # 检查是否已安装 check_installed() { local installed=false # 检查服务文件是否存在 if [ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]; then installed=true fi # 检查二进制文件是否存在 if [ -f "$INSTALL_DIR/$BINARY_NAME" ]; then installed=true fi # 检查源码目录是否存在 if [ -d "$SOURCE_DIR" ]; then installed=true fi if [ "$installed" = false ]; then return 1 fi return 0 } # 停止服务 stop_service() { echo -e "${BLUE}停止服务...${NC}" # 停止 systemd 服务 if systemctl is-active --quiet ${SERVICE_NAME} 2>/dev/null; then echo -e "${BLUE} 正在停止 systemd 服务...${NC}" sudo systemctl stop ${SERVICE_NAME} 2>/dev/null || true sleep 2 fi # 清理残留进程 if pgrep -f "$BINARY_NAME" > /dev/null 2>&1; then echo -e "${BLUE} 清理残留进程...${NC}" sudo pkill -f "$BINARY_NAME" 2>/dev/null || true sleep 1 # 再次检查,如果还有进程则强制杀死 if pgrep -f "$BINARY_NAME" > /dev/null 2>&1; then echo -e "${YELLOW} 强制清理残留进程...${NC}" sudo pkill -9 -f "$BINARY_NAME" 2>/dev/null || true sleep 1 fi fi # 如果使用 run.sh 启动的进程(通过 PID 文件) if [ -f "$PID_FILE" ]; then local pid=$(cat "$PID_FILE" 2>/dev/null || echo "") if [ -n "$pid" ] && kill -0 "$pid" 2>/dev/null; then echo -e "${BLUE} 停止通过 run.sh 启动的进程 (PID: $pid)...${NC}" kill "$pid" 2>/dev/null || true sleep 1 if kill -0 "$pid" 2>/dev/null; then kill -9 "$pid" 2>/dev/null || true fi fi fi echo -e "${GREEN}✓ 服务已停止${NC}" } # 禁用服务 disable_service() { echo -e "${BLUE}禁用服务...${NC}" if systemctl is-enabled --quiet ${SERVICE_NAME} 2>/dev/null; then sudo systemctl disable ${SERVICE_NAME} 2>/dev/null || true echo -e "${GREEN}✓ 服务已禁用${NC}" else echo -e "${BLUE} 服务未启用,跳过${NC}" fi } # 删除服务文件 remove_service_files() { echo -e "${BLUE}删除服务文件...${NC}" local removed=false # 删除 systemd 服务文件 if [ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]; then sudo rm -f /etc/systemd/system/${SERVICE_NAME}.service echo -e "${GREEN}✓ 已删除服务文件: /etc/systemd/system/${SERVICE_NAME}.service${NC}" removed=true fi # 删除可能的 override 配置目录 if [ -d "/etc/systemd/system/${SERVICE_NAME}.service.d" ]; then sudo rm -rf /etc/systemd/system/${SERVICE_NAME}.service.d echo -e "${GREEN}✓ 已删除服务配置目录: /etc/systemd/system/${SERVICE_NAME}.service.d${NC}" removed=true fi if [ "$removed" = true ]; then # 重新加载 systemd daemon sudo systemctl daemon-reload echo -e "${GREEN}✓ systemd daemon 已重新加载${NC}" else echo -e "${BLUE} 未找到服务文件,跳过${NC}" fi } # 删除二进制文件 remove_binary() { echo -e "${BLUE}删除二进制文件...${NC}" if [ -f "$INSTALL_DIR/$BINARY_NAME" ]; then sudo rm -f "$INSTALL_DIR/$BINARY_NAME" echo -e "${GREEN}✓ 已删除二进制文件: $INSTALL_DIR/$BINARY_NAME${NC}" else echo -e "${BLUE} 未找到二进制文件,跳过${NC}" fi } # 删除源码目录和配置文件 remove_source_directory() { echo -e "${BLUE}删除源码目录和配置文件...${NC}" if [ -d "$SOURCE_DIR" ]; then # 显示将要删除的内容 echo -e "${BLUE} 源码目录: $SOURCE_DIR${NC}" # 删除整个源码目录 sudo rm -rf "$SOURCE_DIR" echo -e "${GREEN}✓ 已删除源码目录: $SOURCE_DIR${NC}" else echo -e "${BLUE} 未找到源码目录,跳过${NC}" fi # 额外检查配置文件(如果单独存在) if [ -f "$CONFIG_FILE" ]; then sudo rm -f "$CONFIG_FILE" echo -e "${GREEN}✓ 已删除配置文件: $CONFIG_FILE${NC}" fi } # 清理防火墙规则(可选,默认不删除) remove_firewall_rules() { local remove_firewall="${1:-false}" if [ "$remove_firewall" != "true" ]; then echo -e "${BLUE}跳过防火墙规则清理(默认保留)${NC}" echo -e "${YELLOW} 如需删除防火墙规则,请使用: ./uninstall.sh --remove-firewall${NC}" return fi echo -e "${BLUE}清理防火墙规则(开放2200端口)...${NC}" PORT=2200 FIREWALL_REMOVED=false # 检测 firewalld (CentOS/RHEL 7+, Fedora) if command -v firewall-cmd > /dev/null 2>&1; then if sudo systemctl is-active --quiet firewalld 2>/dev/null; then echo -e "${BLUE} 从 firewalld 删除端口规则...${NC}" if sudo firewall-cmd --permanent --remove-port=${PORT}/tcp > /dev/null 2>&1; then sudo firewall-cmd --reload > /dev/null 2>&1 echo -e "${GREEN}✓ firewalld 规则已删除${NC}" FIREWALL_REMOVED=true fi fi fi # 检测 ufw (Ubuntu/Debian) if command -v ufw > /dev/null 2>&1; then if sudo ufw status > /dev/null 2>&1; then echo -e "${BLUE} 从 ufw 删除端口规则...${NC}" if sudo ufw delete allow ${PORT}/tcp > /dev/null 2>&1; then echo -e "${GREEN}✓ ufw 规则已删除${NC}" FIREWALL_REMOVED=true fi fi fi # 检测 iptables(较老的系统) if command -v iptables > /dev/null 2>&1 && [ "$FIREWALL_REMOVED" = false ]; then if sudo iptables -C INPUT -p tcp --dport ${PORT} -j ACCEPT > /dev/null 2>&1; then echo -e "${BLUE} 从 iptables 删除端口规则...${NC}" if sudo iptables -D INPUT -p tcp --dport ${PORT} -j ACCEPT > /dev/null 2>&1; then echo -e "${GREEN}✓ iptables 规则已删除${NC}" # 尝试保存规则 if command -v iptables-save > /dev/null 2>&1; then if [ -f /etc/redhat-release ]; then sudo iptables-save > /etc/sysconfig/iptables 2>/dev/null || true elif [ -f /etc/debian_version ]; then sudo iptables-save > /etc/iptables/rules.v4 2>/dev/null || true fi fi FIREWALL_REMOVED=true fi fi fi if [ "$FIREWALL_REMOVED" = false ]; then echo -e "${YELLOW}⚠ 未找到防火墙规则或防火墙未启用${NC}" fi } # 显示卸载摘要 show_summary() { echo "" echo -e "${GREEN}========================================${NC}" echo -e "${GREEN} 卸载完成!${NC}" echo -e "${GREEN}========================================${NC}" echo "" echo -e "${BLUE}已删除的内容:${NC}" echo " - systemd 服务文件" echo " - 二进制文件: $INSTALL_DIR/$BINARY_NAME" echo " - 源码目录: $SOURCE_DIR" echo "" echo -e "${YELLOW}注意:${NC}" echo " - 防火墙规则已保留(如需删除请使用 --remove-firewall 参数)" echo " - 如果手动修改过系统配置,请手动清理" echo "" } # 主卸载流程 main() { echo -e "${GREEN}========================================${NC}" echo -e "${GREEN} LinkMaster 节点端卸载程序${NC}" echo -e "${GREEN}========================================${NC}" echo "" # 检查是否已安装 if ! check_installed; then echo -e "${YELLOW}未检测到已安装的 LinkMaster 节点端${NC}" echo -e "${YELLOW}无需卸载${NC}" exit 0 fi # 检查是否需要删除防火墙规则 REMOVE_FIREWALL=false if [ "$1" = "--remove-firewall" ]; then REMOVE_FIREWALL=true fi # 确认卸载 echo -e "${YELLOW}即将卸载 LinkMaster 节点端,此操作将:${NC}" echo " - 停止并禁用服务" echo " - 删除 systemd 服务文件" echo " - 删除二进制文件" echo " - 删除源码目录和配置文件" echo "" # 如果在非交互式环境中,自动确认 if [ -t 0 ]; then read -p "是否继续?(y/N): " -n 1 -r echo "" if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo -e "${YELLOW}已取消卸载${NC}" exit 0 fi else echo -e "${BLUE}非交互式环境,自动确认卸载${NC}" fi echo "" # 执行卸载步骤 stop_service disable_service remove_service_files remove_binary remove_source_directory remove_firewall_rules "$REMOVE_FIREWALL" # 最终检查 echo "" echo -e "${BLUE}最终检查...${NC}" local still_installed=false if check_installed; then still_installed=true fi if [ "$still_installed" = false ]; then show_summary exit 0 else echo -e "${YELLOW}⚠ 部分文件可能未完全删除,请手动检查${NC}" exit 1 fi } # 执行卸载 main "$@"