99 lines
2.9 KiB
Bash
99 lines
2.9 KiB
Bash
#!/usr/bin/env bash
|
||
|
||
set -euo pipefail
|
||
|
||
PORT="${PORT:-15124}"
|
||
HOST="${HOST:-0.0.0.0}"
|
||
APP_MODULE="${APP_MODULE:-app.py}"
|
||
PID_FILE="${PID_FILE:-backend.pid}"
|
||
LOG_FILE="${LOG_FILE:-backend.log}"
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
cd "$SCRIPT_DIR"
|
||
|
||
echo "检查端口 ${PORT} ..."
|
||
if command -v ss >/dev/null 2>&1; then
|
||
if ss -ltn | awk '{print $4}' | grep -Eq "(^|:)${PORT}$"; then
|
||
echo "错误: 端口 ${PORT} 已被占用,请先释放后再启动。"
|
||
exit 1
|
||
fi
|
||
elif command -v netstat >/dev/null 2>&1; then
|
||
if netstat -ltn 2>/dev/null | awk '{print $4}' | grep -Eq "(^|:)${PORT}$"; then
|
||
echo "错误: 端口 ${PORT} 已被占用,请先释放后再启动。"
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "警告: 未找到 ss 或 netstat,跳过端口占用检查。"
|
||
fi
|
||
echo "端口 ${PORT} 未被占用。"
|
||
echo "工作目录已切换至: ${SCRIPT_DIR}"
|
||
|
||
PYTHON_BIN=""
|
||
if [[ -x "${SCRIPT_DIR}/venv/bin/python" ]]; then
|
||
PYTHON_BIN="${SCRIPT_DIR}/venv/bin/python"
|
||
elif [[ -x "${SCRIPT_DIR}/.venv/bin/python" ]]; then
|
||
PYTHON_BIN="${SCRIPT_DIR}/.venv/bin/python"
|
||
elif command -v python3 >/dev/null 2>&1; then
|
||
PYTHON_BIN="$(command -v python3)"
|
||
elif command -v python >/dev/null 2>&1; then
|
||
PYTHON_BIN="$(command -v python)"
|
||
else
|
||
echo "错误: 未找到可用的 Python,请先安装 Python 3.9+。"
|
||
exit 1
|
||
fi
|
||
|
||
echo "使用 Python: ${PYTHON_BIN}"
|
||
"${PYTHON_BIN}" - <<'PY'
|
||
import sys
|
||
major, minor = sys.version_info[:2]
|
||
if (major, minor) < (3, 9):
|
||
print(f"错误: 当前 Python 版本为 {major}.{minor},项目至少需要 Python 3.9。")
|
||
print("原因: requirement.txt 中的 Flask 3.x、pandas 2.x 等依赖不支持 Python 3.6。")
|
||
raise SystemExit(1)
|
||
print(f"Python 版本检查通过: {major}.{minor}")
|
||
PY
|
||
|
||
if [[ ! -f "requirement.txt" ]]; then
|
||
echo "错误: 未找到 requirement.txt。"
|
||
exit 1
|
||
fi
|
||
|
||
echo "检查关键依赖 ..."
|
||
if ! "${PYTHON_BIN}" - <<'PY'
|
||
import importlib.util
|
||
modules = ("flask", "flask_cors", "pymysql", "werkzeug")
|
||
missing = [name for name in modules if importlib.util.find_spec(name) is None]
|
||
if missing:
|
||
print("缺少依赖: " + ", ".join(missing))
|
||
raise SystemExit(1)
|
||
print("关键依赖已安装。")
|
||
PY
|
||
then
|
||
echo "开始安装 requirement.txt ..."
|
||
"${PYTHON_BIN}" -m pip install --upgrade pip
|
||
"${PYTHON_BIN}" -m pip install -r requirement.txt
|
||
fi
|
||
|
||
if [[ -f "${PID_FILE}" ]]; then
|
||
OLD_PID="$(cat "${PID_FILE}" 2>/dev/null || true)"
|
||
if [[ -n "${OLD_PID}" ]] && kill -0 "${OLD_PID}" 2>/dev/null; then
|
||
echo "错误: 检测到服务已在运行,PID=${OLD_PID}"
|
||
exit 1
|
||
fi
|
||
rm -f "${PID_FILE}"
|
||
fi
|
||
|
||
echo "启动 Flask 服务 ${HOST}:${PORT} ..."
|
||
nohup "${PYTHON_BIN}" "${APP_MODULE}" >> "${LOG_FILE}" 2>&1 &
|
||
NEW_PID=$!
|
||
echo "${NEW_PID}" > "${PID_FILE}"
|
||
|
||
sleep 2
|
||
if kill -0 "${NEW_PID}" 2>/dev/null; then
|
||
echo "启动成功,PID=${NEW_PID}"
|
||
echo "日志文件: ${SCRIPT_DIR}/${LOG_FILE}"
|
||
else
|
||
echo "错误: 服务启动失败,请检查日志 ${SCRIPT_DIR}/${LOG_FILE}"
|
||
exit 1
|
||
fi
|