Support docker containers

This commit is contained in:
Taoyu Yang
2026-02-14 08:35:35 +00:00
parent 48d2d90ee5
commit 87397bb62e
3 changed files with 64 additions and 25 deletions

View File

@ -35,7 +35,9 @@ PID_FILE="$CLASH_HOME/temp/clash.pid"
SUBSCRIPTION_FILE="$CLASH_HOME/conf/subscriptions.list"
use_systemd() {
command -v systemctl >/dev/null 2>&1
command -v systemctl >/dev/null 2>&1 || return 1
systemctl show --property=Version --value >/dev/null 2>&1 || return 1
return 0
}
action_with_systemd() {
@ -78,10 +80,11 @@ set_env_var() {
echo "[ERROR] 未找到 .env 文件: $ENV_FILE" >&2
exit 1
fi
local escaped
local escaped escaped_sed
escaped=$(printf "%s" "$value" | sed "s/'/'\"'\"'/g")
escaped_sed=$(printf "%s" "$escaped" | sed 's/[\\&@]/\\&/g')
if grep -q "^export ${key}=" "$ENV_FILE"; then
sed -i "s@^export ${key}=.*@export ${key}='${escaped}'@" "$ENV_FILE"
sed -i "s@^export ${key}=.*@export ${key}='${escaped_sed}'@" "$ENV_FILE"
else
echo "export ${key}='${escaped}'" >> "$ENV_FILE"
fi

View File

@ -351,13 +351,26 @@ read_secret_from_config() {
printf '%s' "$s"
}
# 判断 systemd 是否可用(仅有 systemctl 命令但 PID 1 不是 systemd 时视为不可用)
systemd_ready() {
command -v systemctl >/dev/null 2>&1 || return 1
systemctl show --property=Version --value >/dev/null 2>&1 || return 1
return 0
}
# =========================
# systemd 安装与启动
# =========================
Service_Enabled="unknown"
Service_Started="unknown"
Systemd_Usable="false"
if command -v systemctl >/dev/null 2>&1; then
if systemd_ready; then
Systemd_Usable="true"
fi
if [ "$Systemd_Usable" = "true" ]; then
if [ "${CLASH_ENABLE_SERVICE:-true}" = "true" ] || [ "${CLASH_START_SERVICE:-true}" = "true" ]; then
CLASH_SERVICE_USER="$Service_User" CLASH_SERVICE_GROUP="$Service_Group" "$Install_Dir/scripts/install_systemd.sh"
if [ "${CLASH_ENABLE_SERVICE:-true}" = "true" ]; then
@ -378,8 +391,17 @@ if command -v systemctl >/dev/null 2>&1; then
else
Service_Started="inactive"
fi
else
info "已按配置跳过 systemd 服务安装与启动CLASH_ENABLE_SERVICE=false 且 CLASH_START_SERVICE=false"
Service_Enabled="disabled"
Service_Started="inactive"
fi
else
if command -v systemctl >/dev/null 2>&1; then
warn "检测到 systemctl 命令,但当前环境不可用 systemd常见于 Docker 容器),已跳过服务单元生成"
else
warn "未检测到 systemd已跳过服务单元生成"
fi
fi
# =========================
@ -394,7 +416,7 @@ install_profiled() {
[ "$http_port" = "auto" ] && http_port="7890"
# 只写 IPv4 loopback避免某些环境 ::1 解析问题
sudo tee "$PROFILED_FILE" >/dev/null <<EOF
tee "$PROFILED_FILE" >/dev/null <<EOF
# Clash for Linux proxy helpers
# Auto-generated by clash-for-linux installer.
@ -425,7 +447,7 @@ proxy_status() {
}
EOF
sudo chmod 644 "$PROFILED_FILE"
chmod 644 "$PROFILED_FILE"
}
install_profiled || true
@ -448,7 +470,7 @@ log "📦 安装目录:$(path "${Install_Dir}")"
log "👤 运行用户:${Service_User}:${Service_Group}"
log "🔧 服务名称:${Service_Name}.service"
if command -v systemctl >/dev/null 2>&1; then
if [ "$Systemd_Usable" = "true" ]; then
section "服务状态"
se="${Service_Enabled:-unknown}"
@ -464,6 +486,11 @@ if command -v systemctl >/dev/null 2>&1; then
log "${C_BOLD}常用命令:${C_NC}"
log " $(cmd "sudo systemctl status ${Service_Name}.service")"
log " $(cmd "sudo systemctl restart ${Service_Name}.service")"
else
section "服务状态"
warn "当前环境未启用 systemd如 Docker 容器),请使用 clashctl 管理进程"
log " $(cmd "sudo clashctl start")"
log " $(cmd "sudo clashctl restart")"
fi
# =========================
@ -514,7 +541,11 @@ else
log " $(cmd "sudo bash -c 'echo \"CLASH_URL=<订阅地址>\" > ${ENV_FILE}'")"
log ""
log "配置完成后重启服务:"
if [ "$Systemd_Usable" = "true" ]; then
log " $(cmd "sudo systemctl restart ${Service_Name}.service")"
else
log " $(cmd "sudo clashctl restart")"
fi
fi
# =========================
@ -535,7 +566,7 @@ fi
# 启动后快速诊断
# =========================
sleep 1
if command -v journalctl >/dev/null 2>&1; then
if [ "$Systemd_Usable" = "true" ] && command -v journalctl >/dev/null 2>&1; then
if journalctl -u "${Service_Name}.service" -n 50 --no-pager 2>/dev/null \
| grep -q "Clash订阅地址不可访问"; then
warn "服务启动异常:订阅不可用,请检查 CLASH_URL可能过期 / 404 / 被墙)。"

View File

@ -88,6 +88,7 @@ URL="${CLASH_URL:-}"
# 清理可能的 CRLFWindows 写 .env 很常见)
URL="$(printf '%s' "$URL" | tr -d '\r')"
URL="$(printf '%s' "$URL" | sed -E 's/^[[:space:]]+//; s/[[:space:]]+$//')"
#让 bash 子进程能拿到
export CLASH_URL="$URL"
@ -97,6 +98,10 @@ if [ -z "$URL" ] && [ "${SYSTEMD_MODE:-false}" != "true" ]; then
echo "[ERR] CLASH_URL 为空(未配置订阅地址)"
exit 2
fi
if [ -n "$URL" ] && ! printf '%s' "$URL" | grep -Eq '^https?://'; then
echo "[ERR] CLASH_URL 格式无效:必须以 http:// 或 https:// 开头" >&2
exit 2
fi
# 获取 CLASH_SECRET 值:优先 .env其次读取旧 config占位符视为无效最后生成随机值
Secret="${CLASH_SECRET:-}"