diff --git a/uninstall.sh b/uninstall.sh index 6533126..b82a1a6 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -2,17 +2,20 @@ set -euo pipefail # ========================= -# 基础参数(与 install.sh 对齐) +# 参数(对标 install.sh + install_systemd.sh) # ========================= Install_Dir="${CLASH_INSTALL_DIR:-/opt/clash-for-linux}" Service_Name="clash-for-linux" Service_User="${CLASH_SERVICE_USER:-clash}" Service_Group="${CLASH_SERVICE_GROUP:-$Service_User}" +Unit_Path="/etc/systemd/system/${Service_Name}.service" -# 是否删除运行用户/组(默认不删,更安全;想删就 CLASH_REMOVE_USER=true) +# 可选:删除运行用户/组(默认不删) CLASH_REMOVE_USER="${CLASH_REMOVE_USER:-false}" +# ========================= # 彩色输出 +# ========================= RED='\033[31m' GREEN='\033[32m' YELLOW='\033[33m' @@ -35,8 +38,13 @@ info "开始卸载 ${Service_Name} ..." info "Install_Dir=${Install_Dir}" # ========================= -# 1) 停止服务(systemd) +# 1) 优雅停止(优先 shutdown.sh,再 systemd) # ========================= +if [ -f "${Install_Dir}/shutdown.sh" ]; then + info "执行 shutdown.sh(优雅停止)..." + bash "${Install_Dir}/shutdown.sh" >/dev/null 2>&1 || true +fi + if command -v systemctl >/dev/null 2>&1; then info "停止并禁用 systemd 服务..." systemctl stop "${Service_Name}.service" >/dev/null 2>&1 || true @@ -44,97 +52,79 @@ if command -v systemctl >/dev/null 2>&1; then fi # ========================= -# 2) 兜底:杀掉残留进程(防止删目录后仍占端口) -# - 优先按 PID 文件 -# - 再按二进制名/路径兜底 +# 2) 兜底:按 PID 文件杀进程(对标 unit 的 PIDFile) # ========================= -PID_FILE="" -if [ -d "${Install_Dir}/temp" ] && [ -f "${Install_Dir}/temp/clash.pid" ]; then - PID_FILE="${Install_Dir}/temp/clash.pid" -fi - -if [ -n "$PID_FILE" ]; then +PID_FILE="${Install_Dir}/temp/clash.pid" +if [ -f "$PID_FILE" ]; then PID="$(cat "$PID_FILE" 2>/dev/null || true)" if [ -n "${PID:-}" ] && kill -0 "$PID" 2>/dev/null; then - info "检测到 PID_FILE 进程:PID=${PID},尝试停止..." + info "检测到 PID=${PID},尝试停止..." kill "$PID" 2>/dev/null || true sleep 1 if kill -0 "$PID" 2>/dev/null; then - warn "进程仍在运行,执行强制停止:kill -9 ${PID}" + warn "进程仍在运行,强制 kill -9 ${PID}" kill -9 "$PID" 2>/dev/null || true fi - ok "已停止 clash 进程(PID_FILE)" + ok "已停止 clash 进程(PIDFile)" fi fi -# 兜底:按进程名 +# 再兜底:按进程名(系统可能有多个 clash,不建议无脑 pkill -9;先提示再杀) if pgrep -x clash >/dev/null 2>&1; then - warn "检测到残留 clash 进程,执行 pkill..." - pkill clash >/dev/null 2>&1 || true + warn "检测到仍有 clash 进程存在(可能非本项目),尝试温和结束..." + pkill -x clash >/dev/null 2>&1 || true sleep 1 fi if pgrep -x clash >/dev/null 2>&1; then - warn "clash 仍残留,执行 pkill -9..." - pkill -9 clash >/dev/null 2>&1 || true + warn "仍残留 clash 进程,执行 pkill -9(可能影响其它 clash 实例)..." + pkill -9 -x clash >/dev/null 2>&1 || true fi # ========================= -# 3) 清理 systemd unit(兼容不同路径) +# 3) 删除 systemd unit(对标 install_systemd.sh) # ========================= -remove_unit_file() { - local p="$1" - if [ -f "$p" ]; then - rm -f "$p" - ok "已移除 unit: $p" - fi -} +if [ -f "$Unit_Path" ]; then + rm -f "$Unit_Path" + ok "已移除 systemd 单元: ${Unit_Path}" +fi -remove_unit_file "/etc/systemd/system/${Service_Name}.service" -remove_unit_file "/usr/lib/systemd/system/${Service_Name}.service" -remove_unit_file "/lib/systemd/system/${Service_Name}.service" +# drop-in(万一用户自定义过) +if [ -d "/etc/systemd/system/${Service_Name}.service.d" ]; then + rm -rf "/etc/systemd/system/${Service_Name}.service.d" + ok "已移除 drop-in: /etc/systemd/system/${Service_Name}.service.d" +fi -# reload systemd if command -v systemctl >/dev/null 2>&1; then systemctl daemon-reload >/dev/null 2>&1 || true systemctl reset-failed >/dev/null 2>&1 || true fi # ========================= -# 4) 清理 drop-in(如果有) -# ========================= -if [ -d "/etc/systemd/system/${Service_Name}.service.d" ]; then - rm -rf "/etc/systemd/system/${Service_Name}.service.d" - ok "已移除 drop-in: /etc/systemd/system/${Service_Name}.service.d" -fi - -# ========================= -# 5) 清理环境变量脚本 / 默认配置 +# 4) 清理默认配置/环境脚本/命令入口 # ========================= if [ -f "/etc/default/${Service_Name}" ]; then rm -f "/etc/default/${Service_Name}" ok "已移除: /etc/default/${Service_Name}" fi +# 运行时 Env_File 可能写到 /etc/profile.d 或 temp,这里都清 if [ -f "/etc/profile.d/clash-for-linux.sh" ]; then rm -f "/etc/profile.d/clash-for-linux.sh" ok "已移除: /etc/profile.d/clash-for-linux.sh" fi -# 兼容旧版遗留 -if [ -f "/etc/profile.d/clash.sh" ]; then - warn "检测到旧版 /etc/profile.d/clash.sh(非本脚本必然生成),如确认无用可手动删除" +if [ -f "${Install_Dir}/temp/clash-for-linux.sh" ]; then + rm -f "${Install_Dir}/temp/clash-for-linux.sh" || true + ok "已移除: ${Install_Dir}/temp/clash-for-linux.sh" fi -# ========================= -# 6) 清理命令入口 -# ========================= if [ -f "/usr/local/bin/clashctl" ]; then rm -f "/usr/local/bin/clashctl" ok "已移除: /usr/local/bin/clashctl" fi # ========================= -# 7) 清理安装目录 +# 5) 删除安装目录 # ========================= if [ -d "$Install_Dir" ]; then rm -rf "$Install_Dir" @@ -144,33 +134,31 @@ else fi # ========================= -# 8) 可选:删除运行用户/组(默认不删) +# 6) 可选:删除运行用户/组(默认不删) # ========================= if [ "$CLASH_REMOVE_USER" = "true" ]; then warn "CLASH_REMOVE_USER=true:将尝试删除运行用户/组(若存在且无依赖)" - # 先删用户 if id "$Service_User" >/dev/null 2>&1; then userdel "$Service_User" >/dev/null 2>&1 || true - ok "已删除用户: ${Service_User}(如有依赖可能未删除,请检查)" + ok "已尝试删除用户: ${Service_User}" fi - # 再删组(仅当组存在且无成员依赖时) if getent group "$Service_Group" >/dev/null 2>&1; then groupdel "$Service_Group" >/dev/null 2>&1 || true - ok "已删除组: ${Service_Group}(如有依赖可能未删除,请检查)" + ok "已尝试删除组: ${Service_Group}" fi else - info "默认不删除用户/组(更安全)。如需删除:CLASH_REMOVE_USER=true sudo bash uninstall.sh" + info "默认不删除用户/组。若确认无其它用途,可用:CLASH_REMOVE_USER=true sudo bash uninstall.sh" fi # ========================= -# 9) 清理当前 shell 的代理变量提示(不修改你的 shell,只提示) +# 7) 提示:当前终端代理变量需要手动清 # ========================= echo -warn "如果你之前开启过 proxy_on,当前终端可能还残留代理环境变量。可执行:" +warn "如果你曾执行 proxy_on,当前终端可能仍保留代理环境变量。可执行:" echo " unset http_proxy https_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY" -echo " # 或重新打开一个新终端" +echo " # 或关闭终端重新打开" echo ok "卸载完成 ✅"