@@ -1942,6 +1942,57 @@ system_proxy_supported_state() {
19421942 fi
19431943}
19441944
1945+ persistent_system_proxy_text () {
1946+ local status
1947+
1948+ status=" $( system_proxy_status 2> /dev/null || echo off) "
1949+ if [ " $status " = " on" ]; then
1950+ if system_proxy_matches_runtime 2> /dev/null; then
1951+ echo " on"
1952+ else
1953+ echo " mismatch"
1954+ fi
1955+ return 0
1956+ fi
1957+
1958+ if ! system_proxy_supported; then
1959+ echo " unsupported"
1960+ return 0
1961+ fi
1962+
1963+ echo " off"
1964+ }
1965+
1966+ status_local_proxy_http_url () {
1967+ local port
1968+
1969+ port=" $( status_read_mixed_port 2> /dev/null || true) "
1970+ [ -n " ${port:- } " ] && [ " $port " != " null" ] || return 1
1971+
1972+ echo " http://127.0.0.1:${port} "
1973+ }
1974+
1975+ current_process_proxy_env_text () {
1976+ local expected value
1977+
1978+ expected=" $( status_local_proxy_http_url 2> /dev/null || true) "
1979+ [ -n " ${expected:- } " ] || {
1980+ echo " unknown"
1981+ return 0
1982+ }
1983+
1984+ value=" ${http_proxy:- ${HTTP_PROXY:- ${https_proxy:- ${HTTPS_PROXY:- } } } } "
1985+ [ -n " ${value:- } " ] || value=" ${all_proxy:- ${ALL_PROXY:- } } "
1986+
1987+ if [ -z " ${value:- } " ]; then
1988+ echo " off"
1989+ elif [ " $value " = " $expected " ]; then
1990+ echo " on"
1991+ else
1992+ echo " mismatch"
1993+ fi
1994+ }
1995+
19451996connectivity_issue_code () {
19461997 local active group_count
19471998 local bind_failure_kind
@@ -1996,22 +2047,13 @@ connectivity_issue_code() {
19962047 return 0
19972048 fi
19982049
1999- if ! system_proxy_supported; then
2000- echo " system_proxy_unsupported"
2001- return 0
2002- fi
2003-
2004- if [ " $( system_proxy_status 2> /dev/null || echo off) " != " on" ]; then
2005- echo " system_proxy_off"
2006- return 0
2007- fi
2008-
2009- if ! system_proxy_matches_runtime; then
2010- echo " system_proxy_mismatch"
2011- return 0
2012- fi
2013-
2014- echo " ok"
2050+ case " $( persistent_system_proxy_text) " in
2051+ on) echo " local_proxy_ready_system_proxy_on" ;;
2052+ unsupported) echo " local_proxy_ready_system_proxy_unsupported" ;;
2053+ mismatch) echo " local_proxy_ready_system_proxy_mismatch" ;;
2054+ off) echo " local_proxy_ready_system_proxy_off" ;;
2055+ * ) echo " local_proxy_ready_system_proxy_off" ;;
2056+ esac
20152057}
20162058
20172059connectivity_issue_text () {
@@ -2021,7 +2063,7 @@ connectivity_issue_text() {
20212063 port=" $( runtime_mixed_port_bind_failure_port 2> /dev/null || status_read_mixed_port 2> /dev/null || true) "
20222064
20232065 case " $issue " in
2024- ok) echo " 可用(代理链路已闭环 )" ;;
2066+ ok|local_proxy_ready_system_proxy_on ) echo " 可用(本地代理已就绪,系统代理已接管 )" ;;
20252067 mixed_port_bind_denied) echo " 不可用(mixed-port ${port:- unknown} 绑定被拒绝)" ;;
20262068 mixed_port_address_in_use) echo " 不可用(mixed-port ${port:- unknown} 端口被占用)" ;;
20272069 mixed_port_bind_failed) echo " 不可用(mixed-port ${port:- unknown} 绑定失败)" ;;
@@ -2030,16 +2072,16 @@ connectivity_issue_text() {
20302072 config_invalid) echo " 异常(当前运行配置不可用)" ;;
20312073 subscription_unhealthy) echo " 异常(当前主订阅不可用)" ;;
20322074 proxy_control_broken) echo " 异常(当前无可用策略组或节点控制面异常)" ;;
2033- system_proxy_unsupported) echo " 未接管(当前环境不支持系统代理 )" ;;
2034- system_proxy_off) echo " 未接管 (系统代理未开启)" ;;
2035- system_proxy_mismatch) echo " 异常(系统代理端口与运行时不一致) " ;;
2075+ system_proxy_unsupported|local_proxy_ready_system_proxy_unsupported ) echo " 本地代理可用,系统流量未自动接管(系统代理持久写入不可用 )" ;;
2076+ system_proxy_off|local_proxy_ready_system_proxy_off ) echo " 本地代理可用,系统流量未自动接管 (系统代理未开启)" ;;
2077+ system_proxy_mismatch|local_proxy_ready_system_proxy_mismatch ) echo " 本地代理可用,但系统代理端口与当前运行端口不一致 " ;;
20362078 * ) echo " 未知" ;;
20372079 esac
20382080}
20392081
20402082connectivity_next_action () {
20412083 case " $( connectivity_issue_code) " in
2042- ok)
2084+ ok|local_proxy_ready_system_proxy_on )
20432085 echo " clashctl select"
20442086 ;;
20452087 runtime_stopped)
@@ -2060,13 +2102,13 @@ connectivity_next_action() {
20602102 proxy_control_broken)
20612103 echo " clashctl status --verbose"
20622104 ;;
2063- system_proxy_unsupported)
2064- echo " clashctl doctor "
2105+ system_proxy_unsupported|local_proxy_ready_system_proxy_unsupported )
2106+ echo " 浏览器/应用手动设置代理,或在当前 Shell 使用 clashon "
20652107 ;;
2066- system_proxy_off)
2067- echo " clashon"
2108+ system_proxy_off|local_proxy_ready_system_proxy_off )
2109+ echo " 浏览器/应用手动设置代理,或在当前 Shell 使用 clashon"
20682110 ;;
2069- system_proxy_mismatch)
2111+ system_proxy_mismatch|local_proxy_ready_system_proxy_mismatch )
20702112 echo " clashoff && clashon"
20712113 ;;
20722114 * )
@@ -2078,7 +2120,7 @@ connectivity_next_action() {
20782120connectivity_evidence_lines () {
20792121 local runtime_running controller_ok build_status subscription_status
20802122 local group_count expected_proxy actual_proxy active config_source
2081- local system_proxy_state system_proxy_supported_text
2123+ local system_proxy_state system_proxy_supported_text process_proxy_env mixed_port local_proxy_listening
20822124 local bind_failure_kind bind_failure_line
20832125
20842126 if status_is_running; then
@@ -2098,12 +2140,21 @@ connectivity_evidence_lines() {
20982140 group_count=" $( proxy_group_count 2> /dev/null || echo 0) "
20992141 active=" $( active_subscription_name 2> /dev/null || true) "
21002142 config_source=" $( status_runtime_config_source 2> /dev/null || true) "
2101- expected_proxy=" $( proxy_http_url 2> /dev/null || true) "
2143+ expected_proxy=" $( status_local_proxy_http_url 2> /dev/null || true) "
2144+ mixed_port=" $( status_read_mixed_port 2> /dev/null || true) "
2145+ local_proxy_listening=" false"
2146+ if [ -n " ${mixed_port:- } " ] && [ " $mixed_port " != " null" ] && is_port_in_use " $mixed_port " ; then
2147+ local_proxy_listening=" true"
2148+ fi
21022149 actual_proxy=" $( system_proxy_http_value 2> /dev/null || true) "
2103- system_proxy_state=" $( system_proxy_status 2> /dev/null || echo off ) "
2150+ system_proxy_state=" $( persistent_system_proxy_text ) "
21042151 system_proxy_supported_text=" $( system_proxy_supported_state) "
2152+ process_proxy_env=" $( current_process_proxy_env_text) "
21052153 bind_failure_kind=" $( runtime_mixed_port_bind_failure_kind 2> /dev/null || true) "
21062154 bind_failure_line=" $( runtime_mixed_port_bind_failure_line 2> /dev/null || true) "
2155+ case " ${group_count:- 0} " in
2156+ ' ' |* [!0-9]* ) group_count=0 ;;
2157+ esac
21072158
21082159 echo " • runtime_running = ${runtime_running:- false} "
21092160 echo " • controller_reachable = ${controller_ok:- false} "
@@ -2115,16 +2166,15 @@ connectivity_evidence_lines() {
21152166 echo " • config_source = ${config_source:- unknown} "
21162167 echo " • proxy_group_count = ${group_count:- 0} "
21172168
2118- echo " • system_proxy_supported = ${system_proxy_supported_text:- false} "
2119- echo " • system_proxy_enabled = ${system_proxy_state:- off} "
2169+ echo " • local_proxy_listening = ${local_proxy_listening:- false} "
2170+ [ -n " ${expected_proxy:- } " ] && echo " • local_proxy_http = $expected_proxy "
2171+ echo " • system_proxy_persistent_supported = ${system_proxy_supported_text:- false} "
2172+ echo " • system_proxy_persistent_status = ${system_proxy_state:- off} "
2173+ echo " • current_process_proxy_env = ${process_proxy_env:- unknown} "
21202174 echo " • runtime_backend = $( runtime_backend 2> /dev/null || echo unknown) "
21212175 echo " • boot_runtime_autostart = $( status_service_autostart_text) "
21222176 echo " • boot_proxy_keep = $( status_boot_proxy_keep_text) "
21232177 [ -n " ${actual_proxy:- } " ] && echo " • system_proxy_http = ${actual_proxy} "
2124-
2125- if [ -n " ${expected_proxy:- } " ]; then
2126- echo " • runtime_proxy_http = $expected_proxy "
2127- fi
21282178 echo " • tun_enabled = $( status_tun_enabled 2> /dev/null || echo false) "
21292179 echo " • tun_effective = $( status_tun_effective_status 2> /dev/null || echo unknown) "
21302180 echo " • tun_container_mode = $( status_tun_container_mode 2> /dev/null || echo unknown) "
@@ -2331,12 +2381,8 @@ print_status_summary_compact() {
23312381 user_connectivity=" $( connectivity_issue_text) "
23322382 user_risk=" $( status_user_risk_text) "
23332383 current_proxy_brief=" $( status_current_proxy_brief) "
2334- next_action=" $( system_state_default_action 2> /dev/null || echo ' clashctl status --verbose' ) "
2335- if system_proxy_supported; then
2336- system_proxy_text=" $( system_proxy_status 2> /dev/null || echo off) "
2337- else
2338- system_proxy_text=" unsupported"
2339- fi
2384+ next_action=" $( connectivity_next_action 2> /dev/null || system_state_default_action 2> /dev/null || echo ' clashctl status --verbose' ) "
2385+ system_proxy_text=" $( persistent_system_proxy_text 2> /dev/null || echo unknown) "
23402386 if [ -f " $( runtime_dashboard_dir) /index.html" ]; then
23412387 dashboard_text=" 已部署"
23422388 else
@@ -2383,7 +2429,7 @@ print_status_summary_compact() {
23832429 echo " 🐱 开机代理接管:$( status_boot_auto_proxy_text) "
23842430 echo " 🧪 环境模式:$( status_container_mode_text) "
23852431 echo " 🧪 Tun 状态:${tun_text:- 未知} "
2386- echo " 📜 系统代理状态 :${system_proxy_text} "
2432+ echo " 📜 系统代理持久接管 :${system_proxy_text} "
23872433 echo " 🧩 Dashboard:${dashboard_text} (来源:${dashboard_source_text} )"
23882434 echo " 🧩 Dashboard 策略:${dashboard_policy_text} "
23892435 echo " 🔐 控制器密钥:${secret_text} "
@@ -2483,7 +2529,7 @@ print_status_summary_verbose() {
24832529 user_connectivity=" $( connectivity_issue_text) "
24842530 user_risk=" $( status_user_risk_text) "
24852531 current_proxy_brief=" $( status_current_proxy_brief) "
2486- next_action=" $( system_state_default_action 2> /dev/null || echo ' clashctl status --verbose' ) "
2532+ next_action=" $( connectivity_next_action 2> /dev/null || system_state_default_action 2> /dev/null || echo ' clashctl status --verbose' ) "
24872533 install_backend_text=" $( status_runtime_backend_text) "
24882534 install_container_text=" $( status_container_mode_text) "
24892535 install_verify_text=" $( status_install_verify_brief) "
@@ -2497,11 +2543,7 @@ print_status_summary_verbose() {
24972543 tun_verify_result=" $( status_tun_last_verify_result 2> /dev/null || true) "
24982544 tun_verify_reason=" $( status_tun_last_verify_reason 2> /dev/null || true) "
24992545 tun_verify_time=" $( status_tun_last_verify_time 2> /dev/null || true) "
2500- if system_proxy_supported; then
2501- system_proxy_text=" $( system_proxy_status 2> /dev/null || echo off) "
2502- else
2503- system_proxy_text=" unsupported"
2504- fi
2546+ system_proxy_text=" $( persistent_system_proxy_text 2> /dev/null || echo unknown) "
25052547 if [ -f " $( runtime_dashboard_dir) /index.html" ]; then
25062548 dashboard_text=" 已部署"
25072549 else
@@ -2577,7 +2619,7 @@ print_status_summary_verbose() {
25772619 echo " 🧪 环境模式:${install_container_text:- unknown} "
25782620 echo " 🧩 安装验证:${install_verify_text:- unknown} "
25792621 echo " 📜 端口裁决:${port_adjustment_text:- unknown} "
2580- echo " 📜 系统代理状态 :${system_proxy_text} "
2622+ echo " 📜 系统代理持久接管 :${system_proxy_text} "
25812623 echo " 🧩 Dashboard:${dashboard_text} (来源:${dashboard_source_text} )"
25822624 echo " 🧩 Dashboard 策略:${dashboard_policy_text} "
25832625 echo " 🔐 控制器密钥:${secret_text} "
@@ -3612,11 +3654,7 @@ doctor_runtime_events() {
36123654 build_applied=" $( status_runtime_build_applied 2> /dev/null || true) "
36133655 build_applied_time=" $( status_runtime_build_applied_time 2> /dev/null || true) "
36143656 build_applied_reason=" $( status_runtime_build_applied_reason 2> /dev/null || true) "
3615- if system_proxy_supported; then
3616- system_proxy_text=" $( system_proxy_status 2> /dev/null || echo off) "
3617- else
3618- system_proxy_text=" unsupported"
3619- fi
3657+ system_proxy_text=" $( persistent_system_proxy_text 2> /dev/null || echo unknown) "
36203658 if [ -f " $( runtime_dashboard_dir) /index.html" ]; then
36213659 dashboard_status=" 已部署"
36223660 else
@@ -3635,7 +3673,11 @@ doctor_runtime_events() {
36353673
36363674 doctor_ok " 当前风险等级:${risk_level:- unknown} "
36373675 doctor_ok " 当前配置来源:${config_source:- unknown} "
3638- doctor_ok " 系统代理状态:${system_proxy_text} "
3676+ if [ " $system_proxy_text " = " unsupported" ]; then
3677+ doctor_warn " 系统代理持久接管:unsupported(当前用户不可写 $( system_proxy_env_file 2> /dev/null || echo /etc/environment) )"
3678+ else
3679+ doctor_ok " 系统代理持久接管:${system_proxy_text} "
3680+ fi
36393681 doctor_ok " Dashboard 运行目录:${dashboard_status} (来源:${dashboard_source} )"
36403682 doctor_ok " .env 控制器密钥:${secret_status} "
36413683
@@ -4569,10 +4611,12 @@ doctor_primary_conclusion() {
45694611}
45704612
45714613doctor_recommendation_lines () {
4572- local active_sub bind_failure_kind
4614+ local active_sub bind_failure_kind system_proxy_text mixed_port
45734615
45744616 active_sub=" $( active_subscription_name 2> /dev/null || true) "
45754617 bind_failure_kind=" $( runtime_mixed_port_bind_failure_kind 2> /dev/null || true) "
4618+ system_proxy_text=" $( persistent_system_proxy_text 2> /dev/null || echo unknown) "
4619+ mixed_port=" $( status_read_mixed_port 2> /dev/null || true) "
45764620
45774621 if ! runtime_config_exists; then
45784622 if [ -n " $( subscription_url 2> /dev/null || true) " ]; then
@@ -4609,19 +4653,35 @@ doctor_recommendation_lines() {
46094653 return 0
46104654 fi
46114655
4612- echo " 💡 clashctl status"
4613- echo " 💡 clashctl select"
4656+ case " $system_proxy_text " in
4657+ unsupported|off)
4658+ if [ -n " ${mixed_port:- } " ] && [ " $mixed_port " != " null" ]; then
4659+ echo " 💡 浏览器/应用手动设置 HTTP 代理:http://127.0.0.1:${mixed_port} "
4660+ fi
4661+ echo " 💡 当前 Shell 可使用 clashon 注入代理变量"
4662+ ;;
4663+ mismatch)
4664+ echo " 💡 clashoff && clashon"
4665+ ;;
4666+ * )
4667+ echo " 💡 clashctl status"
4668+ echo " 💡 clashctl select"
4669+ ;;
4670+ esac
46144671}
46154672
46164673doctor_evidence_lines () {
46174674 local active_sub mixed_port controller bind_failure_kind bind_failure_line dns_port
4675+ local system_proxy_text process_proxy_env
46184676
46194677 active_sub=" $( active_subscription_name 2> /dev/null || true) "
46204678 mixed_port=" $( runtime_mixed_port_bind_failure_port 2> /dev/null || status_read_mixed_port 2> /dev/null || true) "
46214679 controller=" $( status_read_controller 2> /dev/null || true) "
46224680 bind_failure_kind=" $( runtime_mixed_port_bind_failure_kind 2> /dev/null || true) "
46234681 bind_failure_line=" $( runtime_mixed_port_bind_failure_line 2> /dev/null || true) "
46244682 dns_port=" $( runtime_config_dns_port 2> /dev/null || true) "
4683+ system_proxy_text=" $( persistent_system_proxy_text 2> /dev/null || echo unknown) "
4684+ process_proxy_env=" $( current_process_proxy_env_text 2> /dev/null || echo unknown) "
46254685
46264686 if runtime_config_exists; then
46274687 echo " 🔍 运行配置:存在"
@@ -4675,11 +4735,15 @@ doctor_evidence_lines() {
46754735 else
46764736 echo " 🔍 代理端口:${mixed_port} (未监听)"
46774737 fi
4738+ echo " 🔍 本地代理:http://127.0.0.1:${mixed_port} "
46784739 fi
46794740
46804741 if [ -n " ${controller:- } " ] && [ " $controller " != " null" ]; then
46814742 echo " 🔍 控制器地址:$( display_controller_local_addr " $controller " 2> /dev/null || echo " $controller " ) "
46824743 fi
4744+
4745+ echo " 🔍 系统代理持久接管:${system_proxy_text} "
4746+ echo " 🔍 当前命令环境代理:${process_proxy_env} "
46834747}
46844748
46854749set_controller_secret () {
0 commit comments