stop.sh 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #!/bin/bash
  2. # 知识工具服务停止脚本
  3. set -e
  4. # 颜色定义
  5. RED='\033[0;31m'
  6. GREEN='\033[0;32m'
  7. YELLOW='\033[1;33m'
  8. NC='\033[0m' # No Color
  9. # 项目根目录
  10. PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  11. PID_FILE="$PROJECT_DIR/app.pid"
  12. echo -e "${GREEN}停止知识工具服务...${NC}"
  13. # 检查PID文件是否存在
  14. if [ ! -f "$PID_FILE" ]; then
  15. echo -e "${YELLOW}未找到PID文件,服务可能未运行${NC}"
  16. exit 0
  17. fi
  18. # 读取PID
  19. PID=$(cat "$PID_FILE")
  20. # 检查进程是否存在
  21. if ! ps -p "$PID" > /dev/null 2>&1; then
  22. echo -e "${YELLOW}进程不存在,清理PID文件${NC}"
  23. rm -f "$PID_FILE"
  24. exit 0
  25. fi
  26. # 停止进程
  27. echo -e "${GREEN}正在停止进程 (PID: $PID)...${NC}"
  28. # 获取进程组ID
  29. PGID=$(ps -o pgid= -p "$PID" 2>/dev/null | tr -d ' ')
  30. # 尝试优雅停止整个进程组
  31. if [ -n "$PGID" ]; then
  32. echo -e "${GREEN}停止进程组 (PGID: $PGID)...${NC}"
  33. kill -TERM -"$PGID" 2>/dev/null || kill -TERM "$PID"
  34. else
  35. kill -TERM "$PID"
  36. fi
  37. # 额外检查并停止可能的后台任务
  38. echo -e "${GREEN}检查并停止相关后台任务...${NC}"
  39. # 查找可能的Python进程
  40. PYTHON_PIDS=$(ps aux | grep -E "(python.*main\.py|uvicorn.*main)" | grep -v grep | awk '{print $2}')
  41. if [ -n "$PYTHON_PIDS" ]; then
  42. echo -e "${YELLOW}发现相关Python进程: $PYTHON_PIDS${NC}"
  43. for py_pid in $PYTHON_PIDS; do
  44. if [ "$py_pid" != "$PID" ]; then
  45. echo -e "${GREEN}停止Python进程: $py_pid${NC}"
  46. kill -TERM "$py_pid" 2>/dev/null || true
  47. fi
  48. done
  49. fi
  50. # 等待进程停止
  51. for i in {1..15}; do
  52. if ! ps -p "$PID" > /dev/null 2>&1; then
  53. echo -e "${GREEN}服务已成功停止${NC}"
  54. rm -f "$PID_FILE"
  55. # 检查端口是否已释放
  56. if command -v lsof >/dev/null 2>&1; then
  57. if ! lsof -i :8079 >/dev/null 2>&1; then
  58. echo -e "${GREEN}端口8079已释放${NC}"
  59. else
  60. echo -e "${YELLOW}警告: 端口8079仍被占用${NC}"
  61. fi
  62. fi
  63. exit 0
  64. fi
  65. echo -e "${YELLOW}等待进程停止... ($i/15)${NC}"
  66. sleep 1
  67. done
  68. # 如果优雅停止失败,强制停止整个进程组
  69. echo -e "${YELLOW}优雅停止失败,强制停止进程组...${NC}"
  70. if [ -n "$PGID" ]; then
  71. kill -KILL -"$PGID" 2>/dev/null || kill -KILL "$PID"
  72. else
  73. kill -KILL "$PID"
  74. fi
  75. # 强制停止所有相关Python进程
  76. PYTHON_PIDS=$(ps aux | grep -E "(python.*main\.py|uvicorn.*main)" | grep -v grep | awk '{print $2}')
  77. if [ -n "$PYTHON_PIDS" ]; then
  78. echo -e "${YELLOW}强制停止所有相关Python进程...${NC}"
  79. for py_pid in $PYTHON_PIDS; do
  80. echo -e "${YELLOW}强制停止Python进程: $py_pid${NC}"
  81. kill -KILL "$py_pid" 2>/dev/null || true
  82. done
  83. fi
  84. # 再次等待
  85. sleep 3
  86. if ! ps -p "$PID" > /dev/null 2>&1; then
  87. echo -e "${GREEN}服务已强制停止${NC}"
  88. rm -f "$PID_FILE"
  89. # 检查端口是否已释放
  90. if command -v lsof >/dev/null 2>&1; then
  91. if ! lsof -i :8079 >/dev/null 2>&1; then
  92. echo -e "${GREEN}端口8079已释放${NC}"
  93. else
  94. echo -e "${YELLOW}警告: 端口8079仍被占用,可能需要手动处理${NC}"
  95. fi
  96. fi
  97. exit 0
  98. else
  99. echo -e "${RED}无法停止服务,请手动处理${NC}"
  100. echo -e "${RED}可以尝试: kill -9 $PID${NC}"
  101. echo -e "${RED}或检查端口占用: lsof -i :8079${NC}"
  102. exit 1
  103. fi