Linux下睡眠重启后Clash-Verge-Rev Tun模式无法联网的解决方案
简介 仅代表 Linux KDE Wayland 环境下的体验
众所周知(,在系统睡眠重启后,Clash-Verge-Rev 在 Tun 模式下会无法联网,一般需要重启应用或者重启内核才能联网。
所以我们要做的事情就是把原来的进程杀掉,然后再重新拉起。
一开始我尝试的是杀死 Clash-Verge-Rev 进程,然后重新启动,但是这在开机脚本的环境下无法实现,因为开机脚本是 Root 环境,无法启动用户程序,就算启动了,也是在 Root 的环境下运行,无法读取到我们用户环境下的配置,但是如果以用户模式运行,又没有权限创建托盘图标和后端进程。
因此我把目光投到 Clash 内核上,通过观察发现内核是运行在 Root 环境下的,即后端是以 Root 权限运行,这样我们就避免了环境问题。
但是直接启动内核的话也无法读取到我们的配置。
通过 ps aux | grep "clash"
观察到,内核的启动还附带有一大串的变量,我们只要复制这一串代码,就可以实现和 GUI 一样的启动效果。
最终我们就得到了想要的效果。
原理 开机脚本 我们可以通过 systemd
创建一个睡眠重启后执行的服务 sleep-restart.service
(根据需要改名)。这个服务负责执行重启 Clash 内核的脚本。
1 2 3 4 5 6 7 8 9 10 11 12 [Unit] Description=Wakeup Hook For Sleep After=suspend.target [Service] Type=simple ExecStart=/path/to/your/script.sh Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
然后我们在 /lib/systemd/system-sleep/
创建一个钩子,在睡眠(或者重启)的时候杀死内核脚本,让 systemd
重新拉起内核。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #!/bin/bash case "$1 " in pre) pid=$(systemctl show -p MainPID --value sleep-restart.service) if [[ -n "$pid " ]]; then kill $pid echo "[$(date) ] Killing process with PID $pid " >> /var/log/clash-wakeup.log else echo "[$(date) ] No PID found for sleep-restart.service" >> /var/log/clash-wakeup.log fi ;; esac
杀死进程和获取启动代码 然后我们需要获得启动代码,通过 ps aux | grep "clash"
查看 Mihomo
字样的进程(Mihomo 为 Clash 的内核)
从 /usr/bin/verge-mihomo
开始复制完整代码,这就是我们需要的启动代码。
我们先用 pgrep -f
获取内核的 PID,获取之后通过 pkill -f
结束内核,然后通过我们刚刚复制的代码来重启内核。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #!/bin/bash log_file="/var/log/clash-wakeup.log" echo "[$(date) ][Hook] Restarting verge-mihomo..." >> "$log_file " for i in {1..30}; do pid=$(pgrep -f verge-mihomo) echo "[$(date) ][Hook] 查找进程 $pid " >> "$log_file " if [[ -n "$pid " ]]; then echo "[$(date) ][Hook] Killing verge-mihomo pid=$pid " >> "$log_file " pkill -f verge-mihomo >> "$log_file " 2>&1 if [ $? -eq 0 ]; then echo "[$(date) ][Hook] pkill 成功" >> "$log_file " else echo "[$(date) ][Hook] pkill 失败,退出码: $?" >> "$log_file " fi break else echo "[$(date) ][Hook] 未找到进程" >> "$log_file " fi sleep 1 done core_path="/usr/bin/verge-mihomo" config_dir="/home/busyo/.local/share/io.github.clash-verge-rev.clash-verge-rev" config_file="$config_dir /clash-verge.yaml" if [[ -x "$core_path " ]]; then exec "$core_path " -d "$config_dir " -f "$config_file " fi
更新日志
调整代码匹配内核的逻辑(原为只匹配了 alpha 版本内核)。 修改执行逻辑,原逻辑会导致第一次重启之后的所有重启都无法触发服务。