start.sh 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #!/bin/bash
  2. # 地磅销售系统后端启动脚本
  3. # 使用方法: ./start.sh [start|stop|restart|status] 或 bash start.sh [start|stop|restart|status]
  4. # 注意: 此脚本需要使用 bash 运行,不要使用 sh start.sh
  5. # 检查是否使用 bash 运行
  6. if [ -z "$BASH_VERSION" ]; then
  7. echo "错误: 此脚本需要使用 bash 运行"
  8. echo "请使用以下命令之一:"
  9. echo " ./start.sh [command]"
  10. echo " bash start.sh [command]"
  11. exit 1
  12. fi
  13. set -e
  14. # 配置
  15. SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
  16. WORK_DIR="$SCRIPT_DIR"
  17. PID_FILE="$WORK_DIR/.dibang-backend.pid"
  18. LOG_FILE="$WORK_DIR/logs/dibang-backend.log"
  19. ENV_FILE="$WORK_DIR/.env.production"
  20. # 创建日志目录
  21. mkdir -p "$WORK_DIR/logs"
  22. # 查找 uv 可执行文件
  23. find_uv() {
  24. # 首先尝试从 PATH 中查找
  25. if command -v uv > /dev/null 2>&1; then
  26. echo "$(command -v uv)"
  27. return 0
  28. fi
  29. # 检查常见安装路径
  30. local uv_paths=(
  31. "/usr/local/bin/uv"
  32. "/usr/bin/uv"
  33. "$HOME/.cargo/bin/uv"
  34. "$HOME/.local/bin/uv"
  35. "/root/.cargo/bin/uv"
  36. "/root/.local/bin/uv"
  37. )
  38. for path in "${uv_paths[@]}"; do
  39. if [ -f "$path" ] && [ -x "$path" ]; then
  40. echo "$path"
  41. return 0
  42. fi
  43. done
  44. return 1
  45. }
  46. # 检查 uv 是否安装
  47. UV_CMD=$(find_uv)
  48. if [ -z "$UV_CMD" ]; then
  49. echo "错误: uv 未安装,请先安装 uv"
  50. echo "安装命令: curl -LsSf https://astral.sh/uv/install.sh | sh"
  51. exit 1
  52. fi
  53. echo "使用 uv: $UV_CMD"
  54. # 检查环境文件
  55. if [ ! -f "$ENV_FILE" ] && [ ! -f "$WORK_DIR/.env" ]; then
  56. echo "警告: 未找到环境配置文件 (.env.production 或 .env)"
  57. echo "将使用默认配置或环境变量"
  58. fi
  59. # 启动服务
  60. start() {
  61. if [ -f "$PID_FILE" ]; then
  62. PID=$(cat "$PID_FILE")
  63. if ps -p "$PID" > /dev/null 2>&1; then
  64. echo "服务已在运行中 (PID: $PID)"
  65. return 1
  66. else
  67. echo "清理过期的 PID 文件"
  68. rm -f "$PID_FILE"
  69. fi
  70. fi
  71. echo "正在启动后端服务..."
  72. cd "$WORK_DIR"
  73. # 设置环境变量
  74. export ENV=prod
  75. export PYTHONUNBUFFERED=1
  76. export UV_INDEX_URL="https://mirrors.aliyun.com/pypi/simple/"
  77. export UV_PUBLIC_PYPI_URL="https://mirrors.aliyun.com/pypi/simple/"
  78. # 使用 nohup 在后台启动
  79. nohup "$UV_CMD" run python app/main.py >> "$LOG_FILE" 2>&1 &
  80. PID=$!
  81. # 保存 PID
  82. echo $PID > "$PID_FILE"
  83. # 等待一下,检查进程是否还在运行
  84. sleep 2
  85. if ps -p "$PID" > /dev/null 2>&1; then
  86. echo "服务启动成功 (PID: $PID)"
  87. echo "日志文件: $LOG_FILE"
  88. echo "查看日志: tail -f $LOG_FILE"
  89. else
  90. echo "服务启动失败,请查看日志: $LOG_FILE"
  91. rm -f "$PID_FILE"
  92. return 1
  93. fi
  94. }
  95. # 停止服务
  96. stop() {
  97. if [ ! -f "$PID_FILE" ]; then
  98. echo "服务未运行(未找到 PID 文件)"
  99. return 1
  100. fi
  101. PID=$(cat "$PID_FILE")
  102. if ! ps -p "$PID" > /dev/null 2>&1; then
  103. echo "服务未运行(进程不存在)"
  104. rm -f "$PID_FILE"
  105. return 1
  106. fi
  107. echo "正在停止服务 (PID: $PID)..."
  108. kill "$PID"
  109. # 等待进程结束
  110. i=0
  111. while [ $i -lt 10 ]; do
  112. if ! ps -p "$PID" > /dev/null 2>&1; then
  113. break
  114. fi
  115. sleep 1
  116. i=$((i + 1))
  117. done
  118. # 如果还在运行,强制杀死
  119. if ps -p "$PID" > /dev/null 2>&1; then
  120. echo "强制停止服务..."
  121. kill -9 "$PID"
  122. fi
  123. rm -f "$PID_FILE"
  124. echo "服务已停止"
  125. }
  126. # 重启服务
  127. restart() {
  128. stop
  129. sleep 2
  130. start
  131. }
  132. # 查看状态
  133. status() {
  134. if [ ! -f "$PID_FILE" ]; then
  135. echo "服务未运行"
  136. return 1
  137. fi
  138. PID=$(cat "$PID_FILE")
  139. if ps -p "$PID" > /dev/null 2>&1; then
  140. echo "服务正在运行 (PID: $PID)"
  141. echo "日志文件: $LOG_FILE"
  142. return 0
  143. else
  144. echo "服务未运行(进程不存在)"
  145. rm -f "$PID_FILE"
  146. return 1
  147. fi
  148. }
  149. # 主逻辑
  150. case "${1:-}" in
  151. start)
  152. start
  153. ;;
  154. stop)
  155. stop
  156. ;;
  157. restart)
  158. restart
  159. ;;
  160. status)
  161. status
  162. ;;
  163. *)
  164. echo "使用方法: $0 {start|stop|restart|status}"
  165. exit 1
  166. ;;
  167. esac
  168. exit $?