Files
clash-for-linux/scripts/run_clash.sh
2026-03-21 13:58:10 +08:00

107 lines
2.6 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
set -euo pipefail
PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
RUNTIME_DIR="$PROJECT_DIR/runtime"
LOG_DIR="$PROJECT_DIR/logs"
CONFIG_FILE="$RUNTIME_DIR/config.yaml"
PID_FILE="$RUNTIME_DIR/clash.pid"
mkdir -p "$RUNTIME_DIR" "$LOG_DIR"
FOREGROUND=false
DAEMON=false
# =========================
# 参数解析
# =========================
for arg in "$@"; do
case "$arg" in
--foreground) FOREGROUND=true ;;
--daemon) DAEMON=true ;;
*)
echo "[ERROR] Unknown arg: $arg" >&2
exit 2
;;
esac
done
if [ "$FOREGROUND" = true ] && [ "$DAEMON" = true ]; then
echo "[ERROR] Cannot use both --foreground and --daemon" >&2
exit 2
fi
if [ "$FOREGROUND" = false ] && [ "$DAEMON" = false ]; then
echo "[ERROR] Must specify --foreground or --daemon" >&2
exit 2
fi
# =========================
# 基础校验
# =========================
if [ ! -s "$CONFIG_FILE" ]; then
echo "[ERROR] runtime config not found: $CONFIG_FILE" >&2
exit 2
fi
if grep -q '\${' "$CONFIG_FILE"; then
echo "[ERROR] unresolved placeholder found in $CONFIG_FILE" >&2
exit 2
fi
# =========================
# 加载依赖
# =========================
# shellcheck disable=SC1091
source "$PROJECT_DIR/scripts/get_cpu_arch.sh"
# shellcheck disable=SC1091
source "$PROJECT_DIR/scripts/resolve_clash.sh"
# shellcheck disable=SC1091
source "$PROJECT_DIR/scripts/service_lib.sh"
# =========================
# 获取二进制
# =========================
CLASH_BIN="$(resolve_clash_bin "$PROJECT_DIR" "${CpuArch:-}")"
if [ ! -x "$CLASH_BIN" ]; then
echo "[ERROR] clash binary not executable: $CLASH_BIN" >&2
exit 2
fi
# =========================
# config 测试(唯一一次)
# =========================
if ! "$CLASH_BIN" -t -f "$CONFIG_FILE" -d "$RUNTIME_DIR" >/dev/null 2>&1; then
echo "[ERROR] clash config test failed: $CONFIG_FILE" >&2
write_run_state "failed" "config-test"
exit 2
fi
# =========================
# 前台模式systemd
# =========================
if [ "$FOREGROUND" = true ]; then
write_run_state "running" "systemd"
exec "$CLASH_BIN" -f "$CONFIG_FILE" -d "$RUNTIME_DIR"
fi
# =========================
# 后台模式script
# =========================
cleanup_dead_pid
if is_script_running; then
pid="$(read_pid 2>/dev/null || true)"
echo "[INFO] clash already running, pid=${pid:-unknown}"
exit 0
fi
nohup "$CLASH_BIN" -f "$CONFIG_FILE" -d "$RUNTIME_DIR" >>"$LOG_DIR/clash.log" 2>&1 &
pid=$!
echo "$pid" > "$PID_FILE"
write_run_state "running" "script" "$pid"
echo "[OK] Clash started in script mode, pid=$pid"