keepalive.sh
4.4 KB
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/bin/bash
# keepalive.sh — Termux 保活 + 进程守护脚本
#
# 功能:
# 1. 获取 wake-lock,防止息屏后 CPU 被冻结
# 2. 检查并启动 hermes server
# 3. 检查并启动 wechat auto-reply plugin
# 4. 进程死了自动重启
#
# 用法:
# chmod +x keepalive.sh
# nohup ./keepalive.sh > keepalive.log 2>&1 &
#
# 前置条件(必须手动设置):
# 1. Android 设置 → 应用 → Termux → 电池优化 → 不优化
# 2. Android 设置 → 应用 → Termux:API → 电池优化 → 不优化
# 3. Android 设置 → 应用 → 微信 → 电池优化 → 不优化
# 4. Android 设置 → 应用 → Termux → 允许自启动
# 5. Termux:API 已安装,并已授予通知访问权限
set -e
# 确保 Termux 工具在 PATH 中(su 环境下可能缺失)
export PATH="/data/data/com.termux/files/usr/bin:$PATH"
HERMES_DIR="${HERMES_DIR:-/data/data/com.termux/files/home/hermes-wechat}"
HERMES_HOST="${HERMES_HOST:-localhost}"
HERMES_PORT="${HERMES_PORT:-3010}"
MY_WXID="${MY_WXID:-}"
MY_NICKNAME="${MY_NICKNAME:-}"
CHECK_INTERVAL_SEC="${CHECK_INTERVAL_SEC:-10}"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
# ── 1. Wake lock ─────────────────────────────────────────────────
termux-wake-lock 2>/dev/null || true
log "Wake lock acquired"
# ── 2. 检查前置条件 ──────────────────────────────────────────────
check_prerequisites() {
_ok=0
if ! command -v termux-notification-list >/dev/null 2>&1; then
log "[WARN] termux-notification-list not found. Install: pkg install termux-api"
_ok=1
fi
if [ ! -d "$HERMES_DIR" ]; then
log "[WARN] HERMES_DIR not found: $HERMES_DIR"
_ok=1
fi
if [ -z "$MY_WXID" ] || [ -z "$MY_NICKNAME" ]; then
log "[WARN] MY_WXID or MY_NICKNAME not set"
log " export MY_WXID=wxid_xxxxxx"
log " export MY_NICKNAME=你的昵称"
_ok=1
fi
return $_ok
}
# ── 3. 检查 hermes server 是否运行 ───────────────────────────────
is_hermes_running() {
curl -s "http://${HERMES_HOST}:${HERMES_PORT}/api/health" >/dev/null 2>&1
}
# ── 4. 启动 hermes server ────────────────────────────────────────
# 必须在 proot Ubuntu 内以 ubuntu 用户运行(Claude CLI 拒绝 root + --dangerously-skip-permissions)
start_hermes() {
log "Starting hermes server in proot Ubuntu user=ubuntu..."
cd "$HERMES_DIR"
nohup proot-distro login ubuntu --user ubuntu -- bash -c \
"cd $HERMES_DIR && . .env && node server/index.js" \
> hermes-server.log 2>&1 &
sleep 5
if is_hermes_running; then
log "Hermes server started PID=$!"
else
log "[WARN] Hermes server may have failed to start, check hermes-server.log"
fi
}
# ── 5. 检查 auto-reply 是否运行 ──────────────────────────────────
is_auto_reply_running() {
pgrep -f "node auto-reply.js" >/dev/null 2>&1
}
# ── 6. 启动 auto-reply ───────────────────────────────────────────
start_auto_reply() {
log "Starting auto-reply..."
cd "$HERMES_DIR/server/services/wechat"
env MY_WXID="$MY_WXID" MY_NICKNAME="$MY_NICKNAME" \
nohup node auto-reply.js > auto-reply.log 2>&1 &
log "Auto-reply started PID=$!"
}
# ── 7. 主循环 ────────────────────────────────────────────────────
log "=== Keepalive started ==="
log "HERMES_DIR=$HERMES_DIR"
log "MY_WXID=${MY_WXID:-not-set}"
log "MY_NICKNAME=${MY_NICKNAME:-not-set}"
if ! check_prerequisites; then
log "[ERROR] Prerequisites check failed, exiting"
exit 1
fi
while true; do
# 检查 hermes
if ! is_hermes_running; then
log "Hermes server not responding, restarting..."
start_hermes
fi
# 检查 auto-reply
if ! is_auto_reply_running; then
log "Auto-reply not running, restarting..."
start_auto_reply
fi
sleep "$CHECK_INTERVAL_SEC"
done