mirror of
https://github.com/wnlen/clash-for-linux.git
synced 2026-10-10 20:23:04 +08:00
@@ -64,6 +64,7 @@ bash install.sh
|
||||
clashctl ls 📡 查看订阅列表
|
||||
📌 高级
|
||||
clashctl tun 🧪 Tun 模式管理
|
||||
clashctl boot 🚦 开机代理接管管理
|
||||
clashctl mixin 🧩 Mixin 配置管理
|
||||
clashctl relay 🔗 多跳节点管理
|
||||
clashctl sub 🧩 订阅高级管理(启用 / 禁用 / 重命名 / 删除)
|
||||
@@ -156,6 +157,20 @@ clashctl sub remove <名称>
|
||||
|
||||
WSL / 普通用户如果无权写入 `/etc/environment`,`clashon` 会自动降级:运行时照常启动,当前 Shell 代理变量生效;系统代理持久接管和开机代理保持不可用。
|
||||
|
||||
### 开机接管(内核 + 代理)
|
||||
|
||||
```bash
|
||||
clashctl boot status
|
||||
clashctl boot on
|
||||
clashctl boot off
|
||||
clashctl boot runtime on|off|status
|
||||
clashctl boot proxy on|off|status
|
||||
```
|
||||
|
||||
- `boot runtime`:只管理内核开机自启(systemd / systemd-user 可用,script 后端为 `unsupported`)。
|
||||
- `boot proxy`:只管理 `/etc/environment` 中的代理持久块(决定开机后是否自动保持代理变量)。
|
||||
- `boot`:整体接管开关,等价于同时编排 runtime + proxy 两层状态。
|
||||
|
||||
### 本地订阅
|
||||
|
||||
可以先手动下载 Clash 格式的订阅 YAML 文件到本地,再通过 `file://` 添加:
|
||||
|
||||
+97
-2
@@ -2618,7 +2618,7 @@ remove_alias_command_wrappers() {
|
||||
}
|
||||
|
||||
install_status_text() {
|
||||
local has_subscription install_ready runtime_ready controller_ready build_status
|
||||
local has_subscription install_ready runtime_ready controller_ready build_status bind_failure_kind
|
||||
local live_runtime="false"
|
||||
local live_controller="false"
|
||||
|
||||
@@ -2632,6 +2632,7 @@ install_status_text() {
|
||||
runtime_ready="$(install_verify_runtime_ready 2>/dev/null || true)"
|
||||
controller_ready="$(install_verify_controller_ready 2>/dev/null || true)"
|
||||
build_status="$(read_build_value "BUILD_LAST_STATUS" 2>/dev/null || true)"
|
||||
bind_failure_kind="$(install_mixed_port_bind_failure_kind 2>/dev/null || true)"
|
||||
|
||||
if status_is_running 2>/dev/null; then
|
||||
live_runtime="true"
|
||||
@@ -2651,6 +2652,11 @@ install_status_text() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -n "${bind_failure_kind:-}" ]; then
|
||||
echo "broken"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "${live_runtime:-false}" = "true" ] && [ "${live_controller:-false}" = "true" ]; then
|
||||
echo "ready"
|
||||
return 0
|
||||
@@ -2672,6 +2678,72 @@ install_status_text() {
|
||||
echo "verifying"
|
||||
}
|
||||
|
||||
install_mixed_port_bind_failure_line() {
|
||||
local log_file="$LOG_DIR/mihomo.out.log"
|
||||
local mixed_port line
|
||||
|
||||
[ -f "$log_file" ] || return 1
|
||||
runtime_config_exists 2>/dev/null || return 1
|
||||
|
||||
mixed_port="$(runtime_config_mixed_port 2>/dev/null || true)"
|
||||
if [ -n "${mixed_port:-}" ] && [ "$mixed_port" != "null" ]; then
|
||||
line="$(grep -Ei "Start Mixed.*server error: listen tcp .*:${mixed_port}:.*(operation not permitted|permission denied|address already in use)" "$log_file" 2>/dev/null | tail -n 1 || true)"
|
||||
fi
|
||||
|
||||
if [ -z "${line:-}" ]; then
|
||||
line="$(grep -Ei 'Start Mixed.*server error: listen tcp .*:.*(operation not permitted|permission denied|address already in use)' "$log_file" 2>/dev/null | tail -n 1 || true)"
|
||||
fi
|
||||
|
||||
[ -n "${line:-}" ] || return 1
|
||||
printf '%s\n' "$line"
|
||||
}
|
||||
|
||||
install_mixed_port_bind_failure_kind() {
|
||||
local line lower
|
||||
|
||||
line="$(install_mixed_port_bind_failure_line 2>/dev/null || true)"
|
||||
[ -n "${line:-}" ] || return 1
|
||||
|
||||
lower="$(printf '%s' "$line" | tr '[:upper:]' '[:lower:]')"
|
||||
case "$lower" in
|
||||
*"address already in use"*)
|
||||
echo "address_in_use"
|
||||
;;
|
||||
*"operation not permitted"*|*"permission denied"*)
|
||||
echo "bind_denied"
|
||||
;;
|
||||
*)
|
||||
echo "bind_failed"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_mixed_port_bind_failure_port() {
|
||||
local port line
|
||||
|
||||
port="$(runtime_config_mixed_port 2>/dev/null || true)"
|
||||
if runtime_port_value_is_valid "$port"; then
|
||||
echo "$port"
|
||||
return 0
|
||||
fi
|
||||
|
||||
line="$(install_mixed_port_bind_failure_line 2>/dev/null || true)"
|
||||
[ -n "${line:-}" ] || return 1
|
||||
printf '%s\n' "$line" | grep -Eo ':[0-9]+:' | tail -n 1 | tr -d ':'
|
||||
}
|
||||
|
||||
install_mixed_port_bind_observation_line() {
|
||||
local mixed_port controller_port
|
||||
|
||||
mixed_port="$(install_mixed_port_bind_failure_port 2>/dev/null || true)"
|
||||
controller_port="$(runtime_config_controller_port 2>/dev/null || true)"
|
||||
|
||||
if proxy_controller_reachable 2>/dev/null \
|
||||
|| { runtime_port_value_is_valid "$controller_port" && is_port_in_use "$controller_port"; }; then
|
||||
echo "配置已加载,控制器已启动,仅代理端口 ${mixed_port:-unknown} 绑定失败;这不是订阅或配置主链失败"
|
||||
fi
|
||||
}
|
||||
|
||||
install_status_label() {
|
||||
case "$(install_status_text)" in
|
||||
ready) echo "ready" ;;
|
||||
@@ -2715,9 +2787,10 @@ install_default_next_action() {
|
||||
}
|
||||
|
||||
install_runtime_brief_line() {
|
||||
local status_text mixed_port controller controller_display
|
||||
local status_text mixed_port controller controller_display bind_failure_kind
|
||||
|
||||
status_text="$(install_status_text)"
|
||||
bind_failure_kind="$(install_mixed_port_bind_failure_kind 2>/dev/null || true)"
|
||||
mixed_port="$(install_plan_mixed_port 2>/dev/null || true)"
|
||||
[ -n "${mixed_port:-}" ] || mixed_port="$(read_env_value "MIXED_PORT" 2>/dev/null || echo "7890")"
|
||||
|
||||
@@ -2750,6 +2823,15 @@ install_runtime_brief_line() {
|
||||
;;
|
||||
broken)
|
||||
echo "❗ 当前状态:broken"
|
||||
case "${bind_failure_kind:-}" in
|
||||
bind_denied)
|
||||
echo "🚫 代理端口绑定被系统拒绝(非端口冲突)"
|
||||
echo "📌 修改端口通常无法解决,请先排查当前环境限制"
|
||||
;;
|
||||
address_in_use)
|
||||
echo "⚠️ 代理端口存在冲突(address already in use)"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "⚪ 当前状态:unknown"
|
||||
@@ -2827,6 +2909,19 @@ print_install_summary() {
|
||||
echo "📦 订阅:$subscription_text"
|
||||
[ -n "${node_count:-}" ] && echo "🔢 节点数量:$node_count"
|
||||
|
||||
case "$(install_mixed_port_bind_failure_kind 2>/dev/null || true)" in
|
||||
bind_denied)
|
||||
echo "🚫 安装后验证:代理端口绑定被系统拒绝(非端口冲突)"
|
||||
echo "📌 这通常是环境限制,修改端口通常无法解决"
|
||||
install_mixed_port_bind_observation_line 2>/dev/null || true
|
||||
echo "👉 下一步:clashctl doctor"
|
||||
echo "👉 日志:clashctl logs mihomo"
|
||||
;;
|
||||
address_in_use)
|
||||
:
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -f "$clashctl_file" ]; then
|
||||
CLASH_UI_BOX_ONLY=1 bash "$clashctl_file" ui || true
|
||||
fi
|
||||
|
||||
@@ -113,8 +113,14 @@ system_proxy_write_block() {
|
||||
mv -f "${tmp}.clean" "$tmp"
|
||||
|
||||
if [ "$mode" = "on" ]; then
|
||||
http_url="$(proxy_http_url)"
|
||||
socks_url="$(proxy_socks_url)"
|
||||
if ! http_url="$(proxy_http_url 2>/dev/null)"; then
|
||||
rm -f "$tmp" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
if ! socks_url="$(proxy_socks_url 2>/dev/null)"; then
|
||||
rm -f "$tmp" 2>/dev/null || true
|
||||
return 1
|
||||
fi
|
||||
no_proxy="$(proxy_no_proxy_value)"
|
||||
|
||||
{
|
||||
|
||||
+15
-1
@@ -312,6 +312,7 @@ post_install_verify() {
|
||||
local has_subscription="false"
|
||||
local runtime_ready="false"
|
||||
local controller_ready="false"
|
||||
local bind_failure_kind="" bind_failure_port=""
|
||||
|
||||
if clashctl_command_available; then
|
||||
write_runtime_value "INSTALL_VERIFY_COMMAND_READY" "true"
|
||||
@@ -348,10 +349,23 @@ post_install_verify() {
|
||||
|
||||
runtime_ready="$(install_verify_runtime_ready 2>/dev/null || true)"
|
||||
controller_ready="$(install_verify_controller_ready 2>/dev/null || true)"
|
||||
bind_failure_kind="$(install_mixed_port_bind_failure_kind 2>/dev/null || true)"
|
||||
bind_failure_port="$(install_mixed_port_bind_failure_port 2>/dev/null || true)"
|
||||
|
||||
if [ "${has_subscription:-false}" = "true" ] && [ "${bind_failure_kind:-}" = "bind_denied" ]; then
|
||||
echo
|
||||
echo "🚫 安装后验证发现:代理端口 ${bind_failure_port:-unknown} 绑定被系统拒绝(非端口冲突)"
|
||||
echo "📌 修改端口通常无法解决;install 阶段不会通过自动换端口处理该问题"
|
||||
install_mixed_port_bind_observation_line 2>/dev/null || true
|
||||
echo "👉 下一步:clashctl doctor"
|
||||
echo "👉 日志:clashctl logs mihomo"
|
||||
echo
|
||||
fi
|
||||
|
||||
if [ "$has_subscription" = "true" ] \
|
||||
&& [ "${runtime_ready:-false}" = "true" ] \
|
||||
&& [ "${controller_ready:-false}" = "true" ]; then
|
||||
&& [ "${controller_ready:-false}" = "true" ] \
|
||||
&& [ "${bind_failure_kind:-}" != "bind_denied" ]; then
|
||||
write_runtime_event_value "RUNTIME_LAST_INSTALL_READY" "true"
|
||||
else
|
||||
write_runtime_event_value "RUNTIME_LAST_INSTALL_READY" "false"
|
||||
|
||||
Reference in New Issue
Block a user