141 lines
3.3 KiB
Bash
141 lines
3.3 KiB
Bash
#!/usr/bin/env bash
|
||||
|
|
# AGV GLB 一键启动(Linux / macOS)
|
|||
|
|
# 用法:
|
|||
|
|
# ./start.sh 启动服务并打开播放页
|
|||
|
|
# ./start.sh --setup 首次部署:创建 .venv 并安装 requirements.txt
|
|||
|
|
# ./start.sh --no-browser 仅启动服务
|
|||
|
|
set -euo pipefail
|
|||
|
|
|
|||
|
|
ROOT="$(cd "$(dirname "$0")" && pwd)"
|
|||
|
|
cd "$ROOT"
|
|||
|
|
|
|||
|
|
SETUP=0
|
|||
|
|
NO_BROWSER=0
|
|||
|
|
PORT="${PORT:-8765}"
|
|||
|
|
|
|||
|
|
for arg in "$@"; do
|
|||
|
|
case "$arg" in
|
|||
|
|
--setup) SETUP=1 ;;
|
|||
|
|
--no-browser) NO_BROWSER=1 ;;
|
|||
|
|
-h|--help)
|
|||
|
|
echo "用法: ./start.sh [--setup] [--no-browser]"
|
|||
|
|
exit 0
|
|||
|
|
;;
|
|||
|
|
esac
|
|||
|
|
done
|
|||
|
|
|
|||
|
|
step() { printf '>> %s\n' "$1"; }
|
|||
|
|
|
|||
|
|
find_python() {
|
|||
|
|
for cmd in python3 python py; do
|
|||
|
|
if command -v "$cmd" >/dev/null 2>&1; then
|
|||
|
|
ver=$("$cmd" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null || true)
|
|||
|
|
major=${ver%%.*}
|
|||
|
|
minor=${ver#*.}
|
|||
|
|
if [ "$major" -gt 3 ] 2>/dev/null || { [ "$major" -eq 3 ] && [ "$minor" -ge 10 ]; }; then
|
|||
|
|
echo "$cmd"
|
|||
|
|
return 0
|
|||
|
|
fi
|
|||
|
|
fi
|
|||
|
|
done
|
|||
|
|
return 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
venv_python() {
|
|||
|
|
if [ -x "$ROOT/.venv/bin/python" ]; then
|
|||
|
|
echo "$ROOT/.venv/bin/python"
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
port_in_use() {
|
|||
|
|
if command -v ss >/dev/null 2>&1; then
|
|||
|
|
ss -ltn 2>/dev/null | grep -q ":${PORT} "
|
|||
|
|
elif command -v lsof >/dev/null 2>&1; then
|
|||
|
|
lsof -iTCP:"$PORT" -sTCP:LISTEN >/dev/null 2>&1
|
|||
|
|
else
|
|||
|
|
return 1
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
wait_ready() {
|
|||
|
|
local url="http://127.0.0.1:${PORT}/api/catalog"
|
|||
|
|
for _ in $(seq 1 75); do
|
|||
|
|
if curl -sf "$url" >/dev/null 2>&1; then
|
|||
|
|
return 0
|
|||
|
|
fi
|
|||
|
|
sleep 0.4
|
|||
|
|
done
|
|||
|
|
return 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
open_browser() {
|
|||
|
|
local url="http://127.0.0.1:${PORT}/viewer/play.html"
|
|||
|
|
if command -v xdg-open >/dev/null 2>&1; then xdg-open "$url"
|
|||
|
|
elif command -v open >/dev/null 2>&1; then open "$url"
|
|||
|
|
fi
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
echo ""
|
|||
|
|
echo " AGV GLB 本地服务"
|
|||
|
|
echo "=================="
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
PY=$(find_python) || { echo "错误: 未找到 Python 3.10+"; exit 1; }
|
|||
|
|
step "Python $($PY --version 2>&1 | awk '{print $2}') ($PY)"
|
|||
|
|
|
|||
|
|
VENV_PY=$(venv_python || true)
|
|||
|
|
|
|||
|
|
if [ "$SETUP" -eq 1 ]; then
|
|||
|
|
step "创建虚拟环境 .venv ..."
|
|||
|
|
if [ ! -x "$ROOT/.venv/bin/python" ]; then
|
|||
|
|
"$PY" -m venv .venv
|
|||
|
|
fi
|
|||
|
|
VENV_PY="$ROOT/.venv/bin/python"
|
|||
|
|
step "安装 Python 依赖 ..."
|
|||
|
|
"$VENV_PY" -m pip install --upgrade pip
|
|||
|
|
"$VENV_PY" -m pip install -r requirements.txt
|
|||
|
|
echo "依赖安装完成。"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
RUN_PY="${VENV_PY:-$PY}"
|
|||
|
|
if [ -n "$VENV_PY" ]; then
|
|||
|
|
step "使用虚拟环境: .venv"
|
|||
|
|
else
|
|||
|
|
step "使用系统 Python(serve.py 无需额外依赖)"
|
|||
|
|
echo "提示: 运行 ./start.sh --setup 可安装 analyze_agv.py 所需依赖"
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
BASE="http://127.0.0.1:${PORT}"
|
|||
|
|
if port_in_use; then
|
|||
|
|
echo "警告: 端口 ${PORT} 已被占用。"
|
|||
|
|
echo " 播放页: ${BASE}/viewer/play.html"
|
|||
|
|
echo " 配置页: ${BASE}/viewer/index.html"
|
|||
|
|
[ "$NO_BROWSER" -eq 0 ] && open_browser
|
|||
|
|
exit 0
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
step "启动 serve.py (端口 ${PORT}) ..."
|
|||
|
|
export PORT
|
|||
|
|
"$RUN_PY" serve.py &
|
|||
|
|
SRV_PID=$!
|
|||
|
|
|
|||
|
|
step "等待服务就绪 ..."
|
|||
|
|
if ! wait_ready; then
|
|||
|
|
echo "错误: 服务在 30 秒内未响应。"
|
|||
|
|
kill "$SRV_PID" 2>/dev/null || true
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
echo ""
|
|||
|
|
echo "服务已启动 (PID ${SRV_PID})"
|
|||
|
|
echo " 播放页: ${BASE}/viewer/play.html"
|
|||
|
|
echo " 配置页: ${BASE}/viewer/index.html"
|
|||
|
|
echo " API: GET ${BASE}/api/catalog | POST ${BASE}/api/agv"
|
|||
|
|
echo ""
|
|||
|
|
echo "关闭服务: kill ${SRV_PID} 或 Ctrl+C"
|
|||
|
|
echo ""
|
|||
|
|
|
|||
|
|
[ "$NO_BROWSER" -eq 0 ] && open_browser
|
|||
|
|
|
|||
|
|
wait "$SRV_PID"
|