96 lines
2.5 KiB
Python
Executable File
96 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Neural Sync 停止器
|
|
停止所有服务
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import platform
|
|
from pathlib import Path
|
|
|
|
# 颜色输出
|
|
class Colors:
|
|
GREEN = '\033[0;32m'
|
|
YELLOW = '\033[1;33m'
|
|
NC = '\033[0m'
|
|
|
|
def print_colored(color, text):
|
|
print(f"{color}{text}{Colors.NC}")
|
|
|
|
def get_project_dir():
|
|
return Path(__file__).parent
|
|
|
|
def kill_port(port):
|
|
"""终止占用指定端口的进程"""
|
|
system = platform.system()
|
|
try:
|
|
if system == "Darwin": # macOS
|
|
result = subprocess.run(["lsof", "-ti", f"{port}"],
|
|
capture_output=True, text=True)
|
|
if result.stdout.strip():
|
|
subprocess.run(["kill", "-9"] + result.stdout.strip().split(),
|
|
capture_output=True)
|
|
return True
|
|
elif system == "Linux":
|
|
subprocess.run(["fuser", "-k", f"{port}/tcp"],
|
|
capture_output=True)
|
|
return True
|
|
except:
|
|
pass
|
|
return False
|
|
|
|
def stop_by_pid(pid_file):
|
|
"""通过 PID 文件停止进程"""
|
|
pid_file_path = get_project_dir() / "logs" / pid_file
|
|
if pid_file_path.exists():
|
|
pid = int(pid_file_path.read_text().strip())
|
|
try:
|
|
os.kill(pid, 9) # SIGKILL
|
|
print_colored(Colors.GREEN, f"✅ 进程已停止 (PID: {pid})")
|
|
pid_file_path.unlink()
|
|
return True
|
|
except ProcessLookupError:
|
|
pid_file_path.unlink()
|
|
return False
|
|
return False
|
|
|
|
def main():
|
|
print_colored(Colors.YELLOW, "🛑 停止 Neural Sync 服务")
|
|
print("=" * 30)
|
|
|
|
stopped = []
|
|
|
|
# 从 PID 文件停止
|
|
if stop_by_pid("backend.pid"):
|
|
stopped.append("后端")
|
|
|
|
if stop_by_pid("frontend.pid"):
|
|
stopped.append("前端")
|
|
|
|
# 清理端口
|
|
if kill_port(8000):
|
|
stopped.append("后端端口")
|
|
|
|
if kill_port(5173):
|
|
stopped.append("前端端口")
|
|
|
|
if stopped:
|
|
print_colored(Colors.GREEN, f"🎉 已停止: {', '.join(stopped)}")
|
|
else:
|
|
print_colored(Colors.YELLOW, "⚠️ 没有找到运行中的服务")
|
|
|
|
# 询问是否停止 Ollama
|
|
try:
|
|
response = input("是否同时停止 Ollama? (y/N): ").strip().lower()
|
|
if response == 'y':
|
|
subprocess.run(["pkill", "-9", "-f", "ollama serve"],
|
|
capture_output=True)
|
|
print_colored(Colors.GREEN, "✅ Ollama 已停止")
|
|
except:
|
|
pass
|
|
|
|
if __name__ == "__main__":
|
|
main()
|