mirror of
https://github.com/KingHWJ/WeReadBoard.git
synced 2026-11-03 18:24:58 +08:00
148 lines
3.9 KiB
Bash
Executable File
148 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
||
# 微信读书数据看板 - 服务启动脚本
|
||
# 用法:
|
||
# ./start_server.sh 启动服务(前台运行)
|
||
# ./start_server.sh daemon 后台守护进程方式启动
|
||
# ./start_server.sh stop 停止服务
|
||
# ./start_server.sh restart 重启服务
|
||
# ./start_server.sh status 查看状态
|
||
|
||
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
if [ -x "$PROJECT_DIR/.venv/bin/python" ]; then
|
||
DEFAULT_PYTHON="$PROJECT_DIR/.venv/bin/python"
|
||
else
|
||
DEFAULT_PYTHON="$(command -v python3 || command -v python)"
|
||
fi
|
||
PYTHON="${PYTHON:-$DEFAULT_PYTHON}"
|
||
PID_FILE="$PROJECT_DIR/.server.pid"
|
||
LOG_FILE="/tmp/weread_server.log"
|
||
# 默认从 8080 启动;也可通过 PORT 或 WEREAD_PORT 指定端口
|
||
PORT="${PORT:-${WEREAD_PORT:-8080}}"
|
||
|
||
cd "$PROJECT_DIR" || exit 1
|
||
|
||
is_running() {
|
||
if [ -f "$PID_FILE" ]; then
|
||
local pid=$(cat "$PID_FILE")
|
||
if kill -0 "$pid" 2>/dev/null; then
|
||
return 0
|
||
fi
|
||
fi
|
||
return 1
|
||
}
|
||
|
||
get_pid() {
|
||
if [ -f "$PID_FILE" ]; then
|
||
local pid=$(cat "$PID_FILE")
|
||
if kill -0 "$pid" 2>/dev/null; then
|
||
echo "$pid"
|
||
return
|
||
fi
|
||
fi
|
||
return 0
|
||
}
|
||
|
||
find_free_port() {
|
||
while lsof -iTCP:"$PORT" -sTCP:LISTEN -t >/dev/null 2>&1; do
|
||
PORT=$((PORT + 1))
|
||
done
|
||
}
|
||
|
||
get_running_port() {
|
||
local pid=$(get_pid)
|
||
local running_port
|
||
|
||
if [ -n "$pid" ]; then
|
||
running_port=$(lsof -Pan -p "$pid" -iTCP -sTCP:LISTEN 2>/dev/null \
|
||
| awk 'NR > 1 {print $9}' \
|
||
| sed -E 's/.*:([0-9]+)$/\1/' \
|
||
| head -1)
|
||
fi
|
||
|
||
echo "${running_port:-$PORT}"
|
||
}
|
||
|
||
stop_server() {
|
||
if is_running; then
|
||
local pid=$(get_pid)
|
||
echo "停止服务 (PID: $pid)..."
|
||
kill "$pid" 2>/dev/null
|
||
sleep 1
|
||
if kill -0 "$pid" 2>/dev/null; then
|
||
kill -9 "$pid" 2>/dev/null
|
||
fi
|
||
rm -f "$PID_FILE"
|
||
echo "已停止"
|
||
else
|
||
echo "服务未运行"
|
||
fi
|
||
}
|
||
|
||
start_foreground() {
|
||
if is_running; then
|
||
local running_port=$(get_running_port)
|
||
echo "服务已在运行 (PID: $(get_pid), 端口: $running_port)"
|
||
echo "访问地址: http://127.0.0.1:$running_port"
|
||
exit 1
|
||
fi
|
||
if [ -z "$PYTHON" ]; then
|
||
echo "未找到可用的 Python 解释器"
|
||
exit 1
|
||
fi
|
||
echo "启动服务(前台模式,端口: $PORT)..."
|
||
echo "访问地址: http://127.0.0.1:$PORT"
|
||
PORT="$PORT" WEREAD_PORT="$PORT" exec "$PYTHON" app.py
|
||
}
|
||
|
||
start_daemon() {
|
||
if [ ! -f "$PID_FILE" ]; then
|
||
find_free_port
|
||
fi
|
||
if is_running; then
|
||
local running_port=$(get_running_port)
|
||
echo "服务已在运行 (PID: $(get_pid), 端口: $running_port)"
|
||
echo "访问地址: http://127.0.0.1:$running_port"
|
||
exit 1
|
||
fi
|
||
if [ -z "$PYTHON" ]; then
|
||
echo "未找到可用的 Python 解释器"
|
||
exit 1
|
||
fi
|
||
echo "启动服务(后台守护模式,端口: $PORT)..."
|
||
PORT="$PORT" WEREAD_PORT="$PORT" nohup "$PYTHON" app.py > "$LOG_FILE" 2>&1 &
|
||
local pid=$!
|
||
echo "$pid" > "$PID_FILE"
|
||
sleep 2
|
||
if kill -0 "$pid" 2>/dev/null; then
|
||
echo "服务已启动 (PID: $pid)"
|
||
echo "端口: $PORT"
|
||
echo "访问地址: http://127.0.0.1:$PORT"
|
||
echo "日志: $LOG_FILE"
|
||
else
|
||
echo "启动失败,请查看日志: $LOG_FILE"
|
||
cat "$LOG_FILE"
|
||
rm -f "$PID_FILE"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
show_status() {
|
||
if is_running; then
|
||
local pid=$(get_pid)
|
||
echo "✅ 服务运行中 (PID: $pid)"
|
||
echo " 端口: $PORT"
|
||
echo " 日志: $LOG_FILE"
|
||
else
|
||
echo "❌ 服务未运行"
|
||
fi
|
||
}
|
||
|
||
case "${1:-start}" in
|
||
start) start_foreground ;;
|
||
daemon) start_daemon ;;
|
||
stop) stop_server ;;
|
||
restart) stop_server; sleep 1; start_daemon ;;
|
||
status) show_status ;;
|
||
*) echo "用法: $0 {start|daemon|stop|restart|status}"; exit 1 ;;
|
||
esac
|