抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

简介

仅代表 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)

# 如果成功获取到 pid,终止进程
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
# 不用在这里重启 service,让 systemd 按照配置自动重启
;;
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

# 启动 verge-mihomo
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

更新日志

2025-04-14

  1. 调整代码匹配内核的逻辑(原为只匹配了 alpha 版本内核)。
  2. 修改执行逻辑,原逻辑会导致第一次重启之后的所有重启都无法触发服务。

2025-04-14

  1. 完成基本内容。

评论