2025-07-02 11:05:23 +08:00
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
"""
|
|
|
|
|
以调试模式启动API服务器,包含详细日志输出
|
|
|
|
|
"""
|
|
|
|
|
import subprocess
|
|
|
|
|
import sys
|
|
|
|
|
import os
|
|
|
|
|
|
2025-07-15 09:40:37 +08:00
|
|
|
|
def kill_process_on_port(port):
|
|
|
|
|
"""查找并终止占用指定端口的进程"""
|
|
|
|
|
if os.name == 'nt': # Windows
|
|
|
|
|
try:
|
|
|
|
|
# 查找占用端口的PID
|
|
|
|
|
command = f"netstat -aon | findstr :{port}"
|
|
|
|
|
result = subprocess.check_output(command, shell=True, text=True, stderr=subprocess.DEVNULL)
|
|
|
|
|
|
|
|
|
|
if not result:
|
|
|
|
|
print(f"端口 {port} 未被占用。")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
for line in result.strip().split('\n'):
|
|
|
|
|
parts = line.strip().split()
|
|
|
|
|
if len(parts) >= 5 and parts[3] == 'LISTENING':
|
|
|
|
|
pid = parts[4]
|
|
|
|
|
print(f"端口 {port} 被PID {pid} 占用,正在终止...")
|
|
|
|
|
# 强制终止进程
|
|
|
|
|
kill_command = f"taskkill /F /PID {pid}"
|
|
|
|
|
subprocess.run(kill_command, shell=True, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
|
|
|
print(f"成功终止PID {pid}。")
|
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
|
# findstr没找到匹配项时会返回错误码1,这是正常情况
|
|
|
|
|
print(f"端口 {port} 未被占用。")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"终止进程时出错: {e}")
|
|
|
|
|
else: # Linux / macOS
|
|
|
|
|
try:
|
|
|
|
|
command = f"lsof -t -i:{port}"
|
|
|
|
|
result = subprocess.check_output(command, shell=True, text=True, stderr=subprocess.DEVNULL)
|
|
|
|
|
pids = result.strip().split('\n')
|
|
|
|
|
for pid in pids:
|
|
|
|
|
if pid:
|
|
|
|
|
print(f"端口 {port} 被PID {pid} 占用,正在终止...")
|
|
|
|
|
kill_command = f"kill -9 {pid}"
|
|
|
|
|
subprocess.run(kill_command, shell=True, check=True)
|
|
|
|
|
print(f"成功终止PID {pid}。")
|
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
|
print(f"端口 {port} 未被占用。")
|
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"终止进程时出错: {e}")
|
|
|
|
|
|
2025-07-02 11:05:23 +08:00
|
|
|
|
def start_api_debug():
|
2025-07-15 09:40:37 +08:00
|
|
|
|
"""启动API服务器(调试模式),并在启动前清理端口"""
|
|
|
|
|
port = 5000
|
|
|
|
|
print(f"准备启动API服务器,将首先清理端口 {port}...")
|
|
|
|
|
print("="*60)
|
|
|
|
|
|
|
|
|
|
# 杀死可能存在的旧进程
|
|
|
|
|
kill_process_on_port(port)
|
|
|
|
|
|
|
|
|
|
print("\n端口清理完成,准备启动新服务...")
|
2025-07-02 11:05:23 +08:00
|
|
|
|
print("="*60)
|
|
|
|
|
|
|
|
|
|
# 切换到正确的目录
|
2025-07-15 09:40:37 +08:00
|
|
|
|
# 脚本的当前目录
|
|
|
|
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
if os.path.basename(script_dir).lower() == 'server':
|
|
|
|
|
# 如果在server目录下,切换到上级目录
|
|
|
|
|
os.chdir(os.path.dirname(script_dir))
|
|
|
|
|
else:
|
|
|
|
|
# 否则,假定在项目根目录
|
|
|
|
|
os.chdir(script_dir)
|
|
|
|
|
|
|
|
|
|
print(f"当前工作目录: {os.getcwd()}")
|
2025-07-02 11:05:23 +08:00
|
|
|
|
|
|
|
|
|
# 启动命令
|
|
|
|
|
cmd = [
|
2025-07-15 09:40:37 +08:00
|
|
|
|
sys.executable,
|
|
|
|
|
"./server/api.py",
|
2025-07-02 11:05:23 +08:00
|
|
|
|
"--debug",
|
|
|
|
|
"--host", "0.0.0.0",
|
2025-07-15 09:40:37 +08:00
|
|
|
|
"--port", str(port)
|
2025-07-02 11:05:23 +08:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
print(f"执行命令: {' '.join(cmd)}")
|
|
|
|
|
print("="*60)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
# 直接运行,输出会实时显示
|
2025-07-15 09:40:37 +08:00
|
|
|
|
# 使用 Popen 以便更好地控制子进程
|
|
|
|
|
process = subprocess.Popen(cmd)
|
|
|
|
|
process.wait() # 等待进程结束
|
|
|
|
|
print(f"API服务器退出,退出码: {process.returncode}")
|
2025-07-02 11:05:23 +08:00
|
|
|
|
|
|
|
|
|
except KeyboardInterrupt:
|
2025-07-15 09:40:37 +08:00
|
|
|
|
print("\n收到中断信号,停止API服务器...")
|
|
|
|
|
process.terminate() # 确保子进程被终止
|
|
|
|
|
process.wait()
|
|
|
|
|
print("服务器已停止。")
|
2025-07-02 11:05:23 +08:00
|
|
|
|
except Exception as e:
|
|
|
|
|
print(f"启动API服务器失败: {e}")
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
start_api_debug()
|