#!/usr/bin/env bash set -euo pipefail # 强制停止 openlist 服务并清理进程 # 用法:curl -fsSL "https://pan.shumengya.top/d/scripts/openlist/stopkill_openlist.sh" | sudo bash SERVICE_NAME="smy-openlist" BIN_NAME="openlist" PORT=5244 log() { printf '[openlist-停止] %s\n' "$*" >&2; } if [ "${EUID:-$(id -u)}" -ne 0 ]; then log "请使用 root 权限运行" exit 1 fi log "正在停止 systemd 服务..." # systemctl stop 会将服务状态置为 inactive,systemd 不会自动重启它,除非手动 start/restart # 即使服务被 disable,systemctl restart 仍然可以启动它 systemctl disable --now "$SERVICE_NAME" 2>/dev/null || true systemctl stop "$SERVICE_NAME" 2>/dev/null || true log "正在检查残留进程..." # 排除当前脚本自身的 PID,防止误杀 current_pid=$$ # 按进程名强制杀 (使用 -x 精确匹配进程名,避免匹配到脚本自身) pids=$(pgrep -x "$BIN_NAME" || true) # 如果 -x 没找到,尝试 -f 但过滤掉脚本自身 if [ -z "$pids" ]; then pids=$(pgrep -f "$BIN_NAME" | grep -v "$current_pid" || true) fi if [ -n "$pids" ]; then log "发现残留进程 PID: $pids,正在强制终止..." kill -9 $pids 2>/dev/null || true fi # 按端口强制杀 pid_port="" if command -v lsof >/dev/null 2>&1; then pid_port=$(lsof -t -i:$PORT 2>/dev/null || true) elif command -v ss >/dev/null 2>&1; then # ss 输出格式处理,提取 pid pid_port=$(ss -lptn "sport = :$PORT" | grep -oE 'pid=[0-9]+' | cut -d= -f2 | sort -u || true) elif command -v netstat >/dev/null 2>&1; then pid_port=$(netstat -nlp | grep ":$PORT " | awk '{print $7}' | cut -d/ -f1 || true) fi if [ -n "$pid_port" ]; then # 再次过滤掉当前 PID (虽然不太可能占用端口,但为了安全) pid_port=$(echo "$pid_port" | grep -v "^$current_pid$") if [ -n "$pid_port" ]; then log "发现端口 $PORT 占用进程 PID: $pid_port,正在强制终止..." kill -9 $pid_port 2>/dev/null || true fi fi # 重置服务失败状态,避免 systemd 认为服务处于错误状态 systemctl reset-failed "$SERVICE_NAME" 2>/dev/null || true # 最终状态检查 log "正在验证服务状态..." if pgrep -x "$BIN_NAME" >/dev/null; then log "警告: 进程仍在运行!" ps -fp $(pgrep -x "$BIN_NAME") else log "openlist 已完全停止 (服务已禁用,进程已清理)。" fi