@@ -554,6 +554,22 @@ status_tun_last_verify_time() {
554554 read_tun_last_verify_time 2> /dev/null || true
555555}
556556
557+ status_tun_last_action () {
558+ read_tun_last_action 2> /dev/null || true
559+ }
560+
561+ status_tun_last_action_result () {
562+ read_tun_last_action_result 2> /dev/null || true
563+ }
564+
565+ status_tun_last_action_reason () {
566+ read_tun_last_action_reason 2> /dev/null || true
567+ }
568+
569+ status_tun_last_action_time () {
570+ read_tun_last_action_time 2> /dev/null || true
571+ }
572+
557573status_tun_effective_status () {
558574 local enabled result
559575
@@ -1730,6 +1746,7 @@ status_risk_reason_lines() {
17301746 local build_block_reason build_block_time
17311747 local fallback_used fallback_time fallback_reason
17321748 local tun_enabled tun_effective tun_container_mode tun_kernel_support tun_verify_reason
1749+ local tun_action_result tun_action_reason tun_action_time
17331750 local bind_failure_text mixed_port
17341751
17351752 build_status=" $( status_build_last_status 2> /dev/null || true) "
@@ -1749,6 +1766,9 @@ status_risk_reason_lines() {
17491766 tun_container_mode=" $( status_tun_container_mode 2> /dev/null || echo unknown) "
17501767 tun_kernel_support=" $( status_tun_kernel_support_level 2> /dev/null || echo unknown) "
17511768 tun_verify_reason=" $( status_tun_last_verify_reason 2> /dev/null || true) "
1769+ tun_action_result=" $( status_tun_last_action_result 2> /dev/null || true) "
1770+ tun_action_reason=" $( status_tun_last_action_reason 2> /dev/null || true) "
1771+ tun_action_time=" $( status_tun_last_action_time 2> /dev/null || true) "
17521772
17531773 if ! status_is_running; then
17541774 if [ -n " ${bind_failure_text:- } " ]; then
@@ -1797,6 +1817,14 @@ status_risk_reason_lines() {
17971817 echo " • 订阅 ${last_risk_name} 连续失败 ${last_risk_fail_count:- ?} 次(阈值 ${last_risk_threshold:- ?} )"
17981818 fi
17991819
1820+ if [ " ${tun_action_result:- } " = " failed" ]; then
1821+ if [ -n " ${tun_action_time:- } " ]; then
1822+ echo " • 最近一次 Tun 配置同步失败:${tun_action_reason:- unknown} @ ${tun_action_time} "
1823+ else
1824+ echo " • 最近一次 Tun 配置同步失败:${tun_action_reason:- unknown} "
1825+ fi
1826+ fi
1827+
18001828 if [ " $tun_enabled " = " true" ] && [ " $tun_effective " != " effective" ]; then
18011829 echo " • Tun 未生效"
18021830 fi
@@ -4698,8 +4726,9 @@ cmd_tun_on() {
46984726 ;;
46994727 esac
47004728
4701- set_tun_enabled " true"
4702- regenerate_config
4729+ if ! sync_tun_target_state " on" " true" ; then
4730+ return 1
4731+ fi
47034732
47044733 if status_is_running; then
47054734 service_restart
@@ -4732,8 +4761,9 @@ cmd_tun_off() {
47324761
47334762 prepare
47344763
4735- set_tun_enabled " false"
4736- regenerate_config
4764+ if ! sync_tun_target_state " off" " false" ; then
4765+ return 1
4766+ fi
47374767
47384768 if status_is_running; then
47394769 service_restart
@@ -5607,10 +5637,14 @@ tun_problem_lines() {
56075637 local enabled env_type config_tun_enabled auto_route
56085638 local effective_result disable_result route_dev
56095639 local container_mode risk_reason
5640+ local last_action_result last_action_reason last_action_time
56105641 local kernel_support
56115642 kernel_support=" $( tun_kernel_support_level 2> /dev/null || echo unknown) "
56125643 container_mode=" $( tun_container_mode 2> /dev/null || echo unknown) "
56135644 risk_reason=" $( tun_container_risk_reason 2> /dev/null || true) "
5645+ last_action_result=" $( status_tun_last_action_result 2> /dev/null || true) "
5646+ last_action_reason=" $( status_tun_last_action_reason 2> /dev/null || true) "
5647+ last_action_time=" $( status_tun_last_action_time 2> /dev/null || true) "
56145648
56155649 enabled=" $( tun_enabled 2> /dev/null || echo false) "
56165650 env_type=" $( container_env_type 2> /dev/null || echo unknown) "
@@ -5657,6 +5691,14 @@ tun_problem_lines() {
56575691 ;;
56585692 esac
56595693
5694+ if [ " ${last_action_result:- } " = " failed" ]; then
5695+ if [ -n " ${last_action_time:- } " ]; then
5696+ echo " • 最近一次 Tun 配置同步失败:${last_action_reason:- unknown} @ ${last_action_time} "
5697+ else
5698+ echo " • 最近一次 Tun 配置同步失败:${last_action_reason:- unknown} "
5699+ fi
5700+ fi
5701+
56605702 if ! runtime_config_exists 2> /dev/null; then
56615703 echo " • 运行时配置不存在"
56625704 return 0
@@ -5693,6 +5735,37 @@ tun_problem_lines() {
56935735 fi
56945736}
56955737
5738+ sync_tun_target_state () {
5739+ local action=" $1 "
5740+ local target=" $2 "
5741+ local previous sync_output rc error_summary
5742+
5743+ previous=" $( tun_enabled 2> /dev/null || echo false) "
5744+ set_tun_enabled " $target "
5745+
5746+ if sync_output=" $( regenerate_config 2>&1 ) " ; then
5747+ return 0
5748+ fi
5749+
5750+ rc=$?
5751+ set_tun_enabled " $previous "
5752+
5753+ error_summary=" $( build_last_error_summary 2> /dev/null || true) "
5754+ if [ -z " ${error_summary:- } " ]; then
5755+ error_summary=" $( printf ' %s\n' " $sync_output " | sed ' /^[[:space:]]*$/d' | tail -n 1) "
5756+ fi
5757+ error_summary=" $( single_line_text " ${error_summary:- 配置重建失败} " ) "
5758+ [ -n " ${error_summary:- } " ] || error_summary=" 配置重建失败"
5759+
5760+ mark_tun_last_action " $action " " failed" " $error_summary "
5761+ mark_tun_last_verification " failed" " config-sync-failed"
5762+
5763+ ui_error " Tun 配置同步失败,已回滚状态文件"
5764+ ui_error " $error_summary "
5765+ ui_next " clashctl tun doctor"
5766+ return " $rc "
5767+ }
5768+
56965769cmd_tun () {
56975770 case " ${1:- } " in
56985771 " " |status)
0 commit comments