diff --git a/start_intent_api.sh b/start_intent_api.sh new file mode 100755 index 0000000..edf1c1e --- /dev/null +++ b/start_intent_api.sh @@ -0,0 +1,111 @@ +#!/usr/bin/env bash + +# 专用脚本:启动 rag2_0.api.intent_recognition_api 服务 +# 功能:启动前检测screen是否存在,存在则结束,最后启动服务 + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SESSION_NAME="intent_recognition_api" +SERVICE_PORT="8001" +START_COMMAND="cd \"$SCRIPT_DIR\" && uv run uvicorn rag2_0.api.intent_recognition_api:app --host 0.0.0.0 --port 8001 --workers 4" + +echo "[脚本] 启动 intent_recognition_api 服务..." + +# 检查screen会话是否存在 +exists_session() { + # 使用严格匹配,避免误判 + if screen -ls 2>/dev/null | grep -q "\\.${SESSION_NAME}\\s"; then + return 0 + fi + return 1 +} + +# 按端口获取监听该端口的任意一个PID,优先用 ss,其次 lsof +pids_on_port() { + # 从 ss 提取 pid 列表 + local ss_pids + ss_pids=$(ss -lptn 2>/dev/null \ + | grep -E ":${SERVICE_PORT}\\b" \ + | awk '{print $NF}' \ + | sed -n 's/.*pid=\([0-9]\+\),.*/\1/p' \ + | sort -u) + if [[ -n "$ss_pids" ]]; then + echo "$ss_pids" + return 0 + fi + # 从 lsof 提取 pid 列表 + if command -v lsof >/dev/null 2>&1; then + local lsof_pids + lsof_pids=$(lsof -nP -i :"$SERVICE_PORT" -sTCP:LISTEN -t 2>/dev/null | sort -u) + if [[ -n "$lsof_pids" ]]; then + echo "$lsof_pids" + return 0 + fi + fi + return 1 +} + +# 根据端口优雅终止(TERM)并在必要时强制(KILL)清理进程 +kill_by_port() { + local pids + pids=$(pids_on_port || true) + if [[ -z "$pids" ]]; then + return 0 + fi + echo "[清理] 端口 $SERVICE_PORT 仍被占用,发送 SIGTERM 到: $pids" + kill -TERM $pids 2>/dev/null || true + sleep 2 + # 再次检查 + local left + left=$(pids_on_port || true) + if [[ -n "$left" ]]; then + echo "[强制] 端口 $SERVICE_PORT 仍占用,发送 SIGKILL 到: $left" + kill -KILL $left 2>/dev/null || true + fi +} + +# 停止已存在的服务 +stop_existing_service() { + # 1) 先尝试关闭 screen 会话 + if exists_session "$SESSION_NAME"; then + echo "[停止] 发现已存在的 screen 会话 '$SESSION_NAME',正在结束..." + screen -S "$SESSION_NAME" -X quit || true + echo "[停止] screen 会话 '$SESSION_NAME' 已结束" + else + echo "[提示] 未发现 screen 会话: $SESSION_NAME" + fi + + # 2) 等待释放端口 + sleep 2 + + # 3) 如果仍占用,按端口清理 + if ss -lptn 2>/dev/null | grep -E -q ":${SERVICE_PORT}\\b" || (command -v lsof >/dev/null 2>&1 && lsof -i :"$SERVICE_PORT" -sTCP:LISTEN >/dev/null 2>&1); then + echo "[清理] 端口 $SERVICE_PORT 仍被占用,正在清理..." + kill_by_port + echo "[清理] 端口 $SERVICE_PORT 清理完成" + fi +} + +# 启动服务 +start_new_service() { + echo "[启动] 准备启动 intent_recognition_api 服务..." + echo "[启动] 启动命令: $START_COMMAND" + screen -dmS "$SESSION_NAME" bash -c "$START_COMMAND" + echo "[启动] intent_recognition_api 服务已启动,screen 会话名: '$SESSION_NAME'" + echo "[启动] 服务运行在端口: $SERVICE_PORT" + echo "[提示] 可使用 'screen -r $SESSION_NAME' 查看服务输出" +} + +# 主流程 +main() { + # 1. 停止已存在的服务 + stop_existing_service + + # 2. 启动新服务 + start_new_service + + echo "[完成] intent_recognition_api 服务启动脚本执行完成" +} + +main