"""启动路由网关服务(后台、无窗口)。 用法: python scripts/serve.py [--port 8000] [--stop] """ import argparse import os import subprocess import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent PID_FILE = ROOT / "_gateway.pid" def start(port: int): if PID_FILE.exists(): old = PID_FILE.read_text().strip() if old: print(f"已有服务运行 (pid={old}),先执行 --stop 再启动。") return out = open(ROOT / "_gateway.out.log", "ab", buffering=0) err = open(ROOT / "_gateway.err.log", "ab", buffering=0) flags = 0x00000008 | 0x08000000 # DETACHED_PROCESS | CREATE_NO_WINDOW proc = subprocess.Popen( [sys.executable, "-m", "uvicorn", "gateway.api:app", "--host", "127.0.0.1", "--port", str(port)], cwd=str(ROOT), stdout=out, stderr=err, creationflags=flags, close_fds=True, ) PID_FILE.write_text(str(proc.pid)) print(f"gateway 已启动 pid={proc.pid} port={port},日志: _gateway.out.log") def stop(): if not PID_FILE.exists(): print("没有运行中的服务。") return pid = int(PID_FILE.read_text().strip()) try: import signal os.kill(pid, signal.SIGTERM) print(f"已发送终止信号 pid={pid}") except ProcessLookupError: print(f"进程 {pid} 不存在,清理 pid 文件。") PID_FILE.unlink(missing_ok=True) if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--port", type=int, default=8000) parser.add_argument("--stop", action="store_true", help="停止服务") args = parser.parse_args() if args.stop: stop() else: start(args.port)