#!/usr/bin/env bash set -euo pipefail SERVICE_NAME="com.chatgpt-register.web" PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" LOG_DIR="${PROJECT_DIR}/logs" LAUNCH_AGENTS_DIR="${HOME}/Library/LaunchAgents" PLIST_PATH="${LAUNCH_AGENTS_DIR}/${SERVICE_NAME}.plist" PYTHON_BIN="${PROJECT_DIR}/.venv/bin/python" HOST="${HOST:-127.0.0.1}" PORT="${PORT:-8080}" while [[ $# -gt 0 ]]; do case "$1" in --host) HOST="${2:-}" shift 2 ;; --port) PORT="${2:-}" shift 2 ;; *) echo "未知参数: $1" echo "用法: $0 [--host 127.0.0.1] [--port 8080]" exit 1 ;; esac done if [[ -z "${HOST}" || -z "${PORT}" ]]; then echo "错误: host/port 不能为空" exit 1 fi if ! [[ "${PORT}" =~ ^[0-9]+$ ]] || (( PORT < 1 || PORT > 65535 )); then echo "错误: 端口必须是 1-65535 的整数" exit 1 fi if [[ ! -x "${PYTHON_BIN}" ]]; then echo "错误: 未找到可执行 Python: ${PYTHON_BIN}" echo "请先创建虚拟环境并安装依赖。" exit 1 fi mkdir -p "${LOG_DIR}" "${LAUNCH_AGENTS_DIR}" cat > "${PLIST_PATH}" < Label ${SERVICE_NAME} ProgramArguments ${PYTHON_BIN} -m uvicorn web_app:app --host ${HOST} --port ${PORT} WorkingDirectory ${PROJECT_DIR} RunAtLoad KeepAlive ThrottleInterval 10 StandardOutPath ${LOG_DIR}/web.stdout.log StandardErrorPath ${LOG_DIR}/web.stderr.log EnvironmentVariables PYTHONUNBUFFERED 1 EOF if launchctl print "gui/$(id -u)/${SERVICE_NAME}" >/dev/null 2>&1; then launchctl bootout "gui/$(id -u)" "${PLIST_PATH}" >/dev/null 2>&1 || true fi launchctl bootstrap "gui/$(id -u)" "${PLIST_PATH}" launchctl enable "gui/$(id -u)/${SERVICE_NAME}" launchctl kickstart -k "gui/$(id -u)/${SERVICE_NAME}" echo "已安装并启动: ${SERVICE_NAME}" echo "配置文件: ${PLIST_PATH}" echo "日志目录: ${LOG_DIR}" echo "访问地址: http://${HOST}:${PORT}"