mirror of
https://github.com/wnlen/clash-for-linux.git
synced 2026-10-10 04:03:04 +08:00
#265 / #272: systemd_user_available() now requires XDG_RUNTIME_DIR and a live D-Bus socket before probing systemctl --user, preventing false-positives in containers (K8s/containerd) where systemctl exists but D-Bus is absent. #274: Remove 'export' from CLASH_FOR_LINUX_SHELL_LOADED guard in profile.sh generation so the variable stays local to the sourcing shell and does not leak into child shells (VSCode terminal, tmux pane, bash subshell), which was causing alias.sh to be skipped and http_proxy not exported in children. #270: Ensure compinit is loaded before bashcompinit in the generated zsh completion script so that compdef is available when bashcompinit registers completions, fixing 'command not found: compdef' on zsh setups that do not call compinit themselves. #271: Extend container_env_type() to detect cgroups v2 + containerd/K8s environments where /proc/1/cgroup only contains '0::/' and neither /.dockerenv nor legacy cgroup keywords are present. Detection now also inspects PID 1 comm and overlay root filesystem as fallbacks. #266: resolve_runtime_ports() accepts an optional config-file hint; when MIXED_PORT is not explicitly set in the environment, the port is read from the config file being normalized. normalize_runtime_config() passes its target file, so a user's 'mixed-port: 7899' in their subscription YAML is preserved instead of being silently overwritten with the default 7890.
This commit is contained in:
+35
-2
@@ -1956,7 +1956,12 @@ systemd_available() {
|
||||
|
||||
systemd_user_available() {
|
||||
is_openwrt && return 1
|
||||
command -v systemctl >/dev/null 2>&1 && systemctl --user list-unit-files >/dev/null 2>&1
|
||||
command -v systemctl >/dev/null 2>&1 || return 1
|
||||
# Require a real user D-Bus socket; avoids false-positives in containers
|
||||
# where systemctl exists but D-Bus is absent (XDG_RUNTIME_DIR unset or no bus socket).
|
||||
[ -n "${XDG_RUNTIME_DIR:-}" ] || return 1
|
||||
[ -S "${XDG_RUNTIME_DIR}/bus" ] || return 1
|
||||
systemctl --user daemon-reload >/dev/null 2>&1
|
||||
}
|
||||
|
||||
is_root_user() {
|
||||
@@ -1972,16 +1977,44 @@ tun_device_readable() {
|
||||
}
|
||||
|
||||
container_env_type() {
|
||||
# Docker: marker file present
|
||||
if [ -f "/.dockerenv" ]; then
|
||||
echo "docker"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# cgroups v1: cgroup path contains runtime keywords
|
||||
if grep -qaE '(docker|containerd|kubepods|lxc)' /proc/1/cgroup 2>/dev/null; then
|
||||
echo "container"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# cgroups v2 + containerd/K8s: /proc/1/cgroup is just "0::/"
|
||||
# Fall back to namespace / filesystem checks
|
||||
if [ -f /proc/1/cgroup ] && grep -q '^0::/' /proc/1/cgroup 2>/dev/null; then
|
||||
# Running as a non-init process tree (PID 1 is not systemd/sysvinit)
|
||||
local _init_comm
|
||||
_init_comm="$(cat /proc/1/comm 2>/dev/null || true)"
|
||||
case "${_init_comm:-}" in
|
||||
systemd|sysvinit|init|launchd|openrc-init)
|
||||
: ;; # real host init, continue to other checks
|
||||
*)
|
||||
# Non-standard PID 1 is a strong container signal
|
||||
echo "container"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Overlay root filesystem is typical of container environments
|
||||
if awk '$5 == "/" { print $1 }' /proc/mounts 2>/dev/null | grep -q 'overlay'; then
|
||||
echo "container"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# No D-Bus session and no /run/systemd/private is another container signal,
|
||||
# but this overlaps with systemd checks elsewhere; skip here to avoid false-positives.
|
||||
|
||||
echo "host"
|
||||
}
|
||||
|
||||
@@ -2548,7 +2581,7 @@ cat > "$profile_file" <<EOF
|
||||
export PATH="$(command_install_dir):\$PATH"
|
||||
|
||||
if [ -n "\${BASH_VERSION:-}" ] && [ -z "\${CLASH_FOR_LINUX_SHELL_LOADED:-}" ]; then
|
||||
export CLASH_FOR_LINUX_SHELL_LOADED="1"
|
||||
CLASH_FOR_LINUX_SHELL_LOADED="1"
|
||||
source "$alias_file"
|
||||
fi
|
||||
|
||||
|
||||
@@ -410,6 +410,10 @@ completion_emit_bash_script() {
|
||||
|
||||
completion_emit_zsh_script() {
|
||||
cat <<'EOF'
|
||||
# Ensure compinit is loaded before bashcompinit (provides compdef)
|
||||
if ! command -v compinit >/dev/null 2>&1; then
|
||||
autoload -Uz compinit && compinit -u 2>/dev/null
|
||||
fi
|
||||
autoload -Uz bashcompinit 2>/dev/null || return 0
|
||||
bashcompinit >/dev/null 2>&1 || return 0
|
||||
EOF
|
||||
|
||||
+13
-2
@@ -806,7 +806,7 @@ normalize_runtime_config() {
|
||||
|
||||
[ -s "$file" ] || die "待规范化的配置文件不存在:$file"
|
||||
|
||||
resolved_ports="$(resolve_runtime_ports)"
|
||||
resolved_ports="$(resolve_runtime_ports "$file")"
|
||||
load_resolved_runtime_ports "$resolved_ports"
|
||||
|
||||
mixed_port="$MIXED_PORT_RESOLVED"
|
||||
@@ -2038,12 +2038,23 @@ load_resolved_runtime_ports() {
|
||||
}
|
||||
|
||||
resolve_runtime_ports() {
|
||||
# Optional: path to a config file to read port from when MIXED_PORT is not set
|
||||
local _hint_config_file="${1:-}"
|
||||
local preferred_mixed preferred_controller preferred_dns
|
||||
local controller_host preferred_controller_port
|
||||
local mixed_port controller_port dns_port
|
||||
local used_ports=""
|
||||
|
||||
preferred_mixed="${MIXED_PORT:-7890}"
|
||||
preferred_mixed="${MIXED_PORT:-}"
|
||||
# When MIXED_PORT is not explicitly configured, honour the port in the config file
|
||||
if [ -z "${preferred_mixed:-}" ] && [ -n "${_hint_config_file:-}" ] && [ -s "${_hint_config_file}" ]; then
|
||||
local _file_port
|
||||
_file_port="$("$(yq_bin)" eval '.["mixed-port"] // .port // ""' "$_hint_config_file" 2>/dev/null | head -n 1)"
|
||||
if [ -n "${_file_port:-}" ] && [ "$_file_port" != "null" ] && is_valid_port_number "$_file_port"; then
|
||||
preferred_mixed="$_file_port"
|
||||
fi
|
||||
fi
|
||||
preferred_mixed="${preferred_mixed:-7890}"
|
||||
preferred_controller="${EXTERNAL_CONTROLLER:-0.0.0.0:9090}"
|
||||
preferred_dns="${CLASH_DNS_PORT:-1053}"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user