diff --git a/doc/3.md b/doc/3.md index e23624f..70662ca 100644 --- a/doc/3.md +++ b/doc/3.md @@ -8,6 +8,22 @@ 编译完成运行 `honoka-chan.exe` 即可,Linux 上可执行文件为 `honoka-chan`。 +如果你在 Linux 上希望常驻运行并方便管理进程,可以直接使用项目根目录下的 `run.sh`: + +```bash +./run.sh start +./run.sh stop +./run.sh restart +./run.sh status +./run.sh logs +``` + +说明: + +- `start` 会自动执行 `go build -o honoka-chan main.go`,然后以 `nohup` 后台运行。 +- PID 文件:`temp/run/honoka-chan.pid` +- 日志文件:`temp/run/honoka-chan.log` + ### 下载服务部署 #### SIF 数据下载服务 diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..dcaf126 --- /dev/null +++ b/run.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +APP_BIN="$ROOT_DIR/honoka-chan" +PID_FILE="$ROOT_DIR/temp/run/honoka-chan.pid" +LOG_FILE="$ROOT_DIR/temp/run/honoka-chan.log" + +mkdir -p "$(dirname "$PID_FILE")" + +build_app() { + if command -v go >/dev/null 2>&1; then + (cd "$ROOT_DIR" && go build -o honoka-chan main.go) + else + echo "Go is not installed, cannot build honoka-chan automatically" + exit 1 + fi +} + +is_running() { + [[ -f "$PID_FILE" ]] || return 1 + local pid + pid="$(cat "$PID_FILE" 2>/dev/null || true)" + [[ -n "${pid:-}" ]] || return 1 + kill -0 "$pid" 2>/dev/null || return 1 + + local args + args="$(ps -p "$pid" -o args= 2>/dev/null || true)" + [[ "$args" == *"$APP_BIN"* || "$args" == *"honoka-chan"* ]] +} + +start_app() { + if is_running; then + echo "honoka-chan is already running, pid=$(cat "$PID_FILE")" + return 0 + fi + + build_app + nohup "$APP_BIN" >>"$LOG_FILE" 2>&1 & + local pid=$! + echo "$pid" >"$PID_FILE" + sleep 1 + + if kill -0 "$pid" 2>/dev/null; then + echo "honoka-chan started successfully, pid=$pid" + else + rm -f "$PID_FILE" + echo "honoka-chan failed to start, check $LOG_FILE" + exit 1 + fi +} + +stop_app() { + if ! is_running; then + rm -f "$PID_FILE" + echo "honoka-chan is not running" + return 0 + fi + + local pid + pid="$(cat "$PID_FILE")" + kill "$pid" 2>/dev/null || true + + for _ in $(seq 1 50); do + if ! kill -0 "$pid" 2>/dev/null; then + rm -f "$PID_FILE" + echo "honoka-chan stopped" + return 0 + fi + sleep 0.2 + done + + kill -9 "$pid" 2>/dev/null || true + rm -f "$PID_FILE" + echo "honoka-chan force stopped" +} + +status_app() { + if is_running; then + echo "honoka-chan is running, pid=$(cat "$PID_FILE")" + else + echo "honoka-chan is not running" + fi +} + +logs_app() { + touch "$LOG_FILE" + tail -f "$LOG_FILE" +} + +usage() { + cat <<'EOF' +Usage: + ./run.sh start Start service + ./run.sh stop Stop service + ./run.sh restart Restart service + ./run.sh status Check status + ./run.sh logs Follow logs +EOF +} + +case "${1:-}" in + start) + start_app + ;; + stop) + stop_app + ;; + restart) + stop_app + start_app + ;; + status) + status_app + ;; + logs) + logs_app + ;; + ""|-h|--help|help) + usage + ;; + *) + echo "Unknown command: $1" + usage + exit 1 + ;; +esac