#!/usr/bin/env bash set -euo pipefail echo "🛑 停止 X-Request (FastAPI)" # 永远从脚本所在目录运行 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" PID_FILE="logs/xrequest.pid" # 读取 .env 文件中的配置 PORT="8000" # 默认端口 # 解析 .env 文件中的 PORT if [ -f ".env" ]; then # 使用 grep 和 sed 来提取 PORT(忽略注释) PORT=$(grep -v '^#' .env | grep '^PORT=' | head -1 | cut -d= -f2 | tr -d '"' || echo "8000") fi echo "📋 使用配置: PORT=$PORT" kill_pid() { local pid="$1" if [ -z "$pid" ]; then return 1 fi # Windows Git Bash: 优先 taskkill(对 python.exe 更稳) if command -v taskkill >/dev/null 2>&1; then taskkill //F //PID "$pid" >/dev/null 2>&1 || true return 0 fi # Linux/macOS kill "$pid" >/dev/null 2>&1 || true sleep 0.3 kill -9 "$pid" >/dev/null 2>&1 || true return 0 } if [ -f "$PID_FILE" ]; then PID="$(cat "$PID_FILE" 2>/dev/null || true)" if [ -n "$PID" ] && kill -0 "$PID" >/dev/null 2>&1; then echo "🔪 终止进程 pid=$PID ..." kill_pid "$PID" rm -f "$PID_FILE" || true echo "✅ 已停止" exit 0 fi # pid 文件存在但进程不存在:清理 rm -f "$PID_FILE" || true fi echo "ℹ️ 未找到有效 PID 文件,尝试按端口 $PORT 查找并停止..." PIDS_BY_PORT="" if command -v netstat >/dev/null 2>&1; then # Windows Git Bash (netstat -ano) PIDS_BY_PORT="$(netstat -ano 2>/dev/null | grep -E "[:.]$PORT[[:space:]]" | grep LISTENING | awk '{print $NF}' | sort -u | tr '\n' ' ' || true)" fi if [ -z "$PIDS_BY_PORT" ] && command -v lsof >/dev/null 2>&1; then PIDS_BY_PORT="$(lsof -ti tcp:$PORT 2>/dev/null | sort -u | tr '\n' ' ' || true)" fi if [ -z "$PIDS_BY_PORT" ] && command -v ss >/dev/null 2>&1; then PIDS_BY_PORT="$(ss -ltnp 2>/dev/null | grep ':$PORT' | sed -n 's/.*pid=\([0-9]\+\).*/\1/p' | sort -u | tr '\n' ' ' || true)" fi if [ -z "$PIDS_BY_PORT" ]; then echo "✅ 未发现 $PORT 端口监听进程(无需停止)" exit 0 fi for p in $PIDS_BY_PORT; do echo "🔪 终止进程 pid=$p (by port $PORT)..." kill_pid "$p" done echo "✅ 已停止(by port $PORT)"