claw-subagent-service 0.0.94 → 0.0.96
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/command/linux/restart.sh
CHANGED
|
@@ -22,10 +22,24 @@ MAX_WAIT=300 # 最长等待5分钟
|
|
|
22
22
|
PORT="18789"
|
|
23
23
|
|
|
24
24
|
# 检测是否在 Docker 环境(无 systemd)
|
|
25
|
+
# 注意:某些 Docker 镜像安装了 systemctl 命令但无法使用
|
|
26
|
+
# 所以同时检查 systemd 是否实际运行
|
|
25
27
|
is_docker() {
|
|
28
|
+
# 方法1: 检查 systemctl 是否可用
|
|
26
29
|
if ! command -v systemctl &>/dev/null; then
|
|
27
30
|
return 0 # 无 systemctl,认为是 Docker
|
|
28
31
|
fi
|
|
32
|
+
|
|
33
|
+
# 方法2: 即使安装了 systemctl,检查 systemd 是否实际运行
|
|
34
|
+
if [ ! -d "/run/systemd/system" ] && [ ! -d "/sys/fs/cgroup/systemd" ]; then
|
|
35
|
+
return 0 # systemd 未运行,认为是 Docker
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# 方法3: 尝试执行 systemctl status,如果失败则认为是 Docker
|
|
39
|
+
if ! systemctl status &>/dev/null; then
|
|
40
|
+
return 0 # systemctl 无法使用,认为是 Docker
|
|
41
|
+
fi
|
|
42
|
+
|
|
29
43
|
return 1
|
|
30
44
|
}
|
|
31
45
|
|
|
@@ -112,6 +126,7 @@ get_openclaw_pid() {
|
|
|
112
126
|
}
|
|
113
127
|
|
|
114
128
|
# 检查端口是否监听
|
|
129
|
+
# 注意:只检查端口,不检查进程。进程存在不等于端口在监听。
|
|
115
130
|
check_port() {
|
|
116
131
|
local port=$1
|
|
117
132
|
if command -v ss &>/dev/null; then
|
|
@@ -126,11 +141,9 @@ check_port() {
|
|
|
126
141
|
elif command -v fuser &>/dev/null; then
|
|
127
142
|
fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
|
|
128
143
|
return $?
|
|
129
|
-
else
|
|
130
|
-
# 降级:直接检查进程
|
|
131
|
-
[ -n "$(get_openclaw_pid)" ]
|
|
132
|
-
return $?
|
|
133
144
|
fi
|
|
145
|
+
# 如果所有工具都不可用,无法准确检查端口,保守返回 1(端口未监听)
|
|
146
|
+
return 1
|
|
134
147
|
}
|
|
135
148
|
|
|
136
149
|
# 等待端口启动
|
package/command/linux/start.sh
CHANGED
|
@@ -22,10 +22,24 @@ MAX_WAIT=300 # 最长等待5分钟
|
|
|
22
22
|
PORT="18789"
|
|
23
23
|
|
|
24
24
|
# 检测是否在 Docker 环境(无 systemd)
|
|
25
|
+
# 注意:某些 Docker 镜像安装了 systemctl 命令但无法使用
|
|
26
|
+
# 所以同时检查 systemd 是否实际运行
|
|
25
27
|
is_docker() {
|
|
28
|
+
# 方法1: 检查 systemctl 是否可用
|
|
26
29
|
if ! command -v systemctl &>/dev/null; then
|
|
27
30
|
return 0 # 无 systemctl,认为是 Docker
|
|
28
31
|
fi
|
|
32
|
+
|
|
33
|
+
# 方法2: 即使安装了 systemctl,检查 systemd 是否实际运行
|
|
34
|
+
if [ ! -d "/run/systemd/system" ] && [ ! -d "/sys/fs/cgroup/systemd" ]; then
|
|
35
|
+
return 0 # systemd 未运行,认为是 Docker
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# 方法3: 尝试执行 systemctl status,如果失败则认为是 Docker
|
|
39
|
+
if ! systemctl status &>/dev/null; then
|
|
40
|
+
return 0 # systemctl 无法使用,认为是 Docker
|
|
41
|
+
fi
|
|
42
|
+
|
|
29
43
|
return 1
|
|
30
44
|
}
|
|
31
45
|
|
|
@@ -112,6 +126,7 @@ get_openclaw_pid() {
|
|
|
112
126
|
}
|
|
113
127
|
|
|
114
128
|
# 检查端口是否监听
|
|
129
|
+
# 注意:只检查端口,不检查进程。进程存在不等于端口在监听。
|
|
115
130
|
check_port() {
|
|
116
131
|
local port=$1
|
|
117
132
|
if command -v ss &>/dev/null; then
|
|
@@ -126,11 +141,9 @@ check_port() {
|
|
|
126
141
|
elif command -v fuser &>/dev/null; then
|
|
127
142
|
fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
|
|
128
143
|
return $?
|
|
129
|
-
else
|
|
130
|
-
# 降级:直接检查进程
|
|
131
|
-
[ -n "$(get_openclaw_pid)" ]
|
|
132
|
-
return $?
|
|
133
144
|
fi
|
|
145
|
+
# 如果所有工具都不可用,无法准确检查端口,保守返回 1(端口未监听)
|
|
146
|
+
return 1
|
|
134
147
|
}
|
|
135
148
|
|
|
136
149
|
# 等待端口启动
|
package/command/linux/status.sh
CHANGED
|
@@ -36,10 +36,24 @@ SERVICE_NAME="openclaw-gateway.service"
|
|
|
36
36
|
PORT="18789"
|
|
37
37
|
|
|
38
38
|
# 检测是否在 Docker 环境(无 systemd)
|
|
39
|
+
# 注意:某些 Docker 镜像安装了 systemctl 命令但无法使用
|
|
40
|
+
# 所以同时检查 systemd 是否实际运行
|
|
39
41
|
is_docker() {
|
|
42
|
+
# 方法1: 检查 systemctl 是否可用
|
|
40
43
|
if ! command -v systemctl &>/dev/null; then
|
|
41
44
|
return 0 # 无 systemctl,认为是 Docker
|
|
42
45
|
fi
|
|
46
|
+
|
|
47
|
+
# 方法2: 即使安装了 systemctl,检查 systemd 是否实际运行
|
|
48
|
+
if [ ! -d "/run/systemd/system" ] && [ ! -d "/sys/fs/cgroup/systemd" ]; then
|
|
49
|
+
return 0 # systemd 未运行,认为是 Docker
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
# 方法3: 尝试执行 systemctl status,如果失败则认为是 Docker
|
|
53
|
+
if ! systemctl status &>/dev/null; then
|
|
54
|
+
return 0 # systemctl 无法使用,认为是 Docker
|
|
55
|
+
fi
|
|
56
|
+
|
|
43
57
|
return 1
|
|
44
58
|
}
|
|
45
59
|
|
|
@@ -126,6 +140,7 @@ get_openclaw_pid() {
|
|
|
126
140
|
}
|
|
127
141
|
|
|
128
142
|
# 检查端口是否监听
|
|
143
|
+
# 注意:只检查端口,不检查进程。进程存在不等于端口在监听。
|
|
129
144
|
check_port() {
|
|
130
145
|
local port=$1
|
|
131
146
|
if command -v ss &>/dev/null; then
|
|
@@ -140,11 +155,9 @@ check_port() {
|
|
|
140
155
|
elif command -v fuser &>/dev/null; then
|
|
141
156
|
fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
|
|
142
157
|
return $?
|
|
143
|
-
else
|
|
144
|
-
# 降级:直接检查进程
|
|
145
|
-
[ -n "$(get_openclaw_pid)" ]
|
|
146
|
-
return $?
|
|
147
158
|
fi
|
|
159
|
+
# 如果所有工具都不可用,无法准确检查端口,保守返回 1(端口未监听)
|
|
160
|
+
return 1
|
|
148
161
|
}
|
|
149
162
|
|
|
150
163
|
# Docker 模式:查看状态
|
package/command/linux/stop.sh
CHANGED
|
@@ -30,10 +30,25 @@ log_error() {
|
|
|
30
30
|
SERVICE_NAME="openclaw-gateway.service"
|
|
31
31
|
|
|
32
32
|
# 检测是否在 Docker 环境(无 systemd)
|
|
33
|
+
# 注意:某些 Docker 镜像安装了 systemctl 命令但无法使用
|
|
34
|
+
# 所以同时检查 systemd 是否实际运行
|
|
33
35
|
is_docker() {
|
|
36
|
+
# 方法1: 检查 systemctl 是否可用
|
|
34
37
|
if ! command -v systemctl &>/dev/null; then
|
|
35
38
|
return 0 # 无 systemctl,认为是 Docker
|
|
36
39
|
fi
|
|
40
|
+
|
|
41
|
+
# 方法2: 即使安装了 systemctl,检查 systemd 是否实际运行
|
|
42
|
+
# 在 Docker 中,/run/systemd/system 通常不存在
|
|
43
|
+
if [ ! -d "/run/systemd/system" ] && [ ! -d "/sys/fs/cgroup/systemd" ]; then
|
|
44
|
+
return 0 # systemd 未运行,认为是 Docker
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# 方法3: 尝试执行 systemctl status,如果失败则认为是 Docker
|
|
48
|
+
if ! systemctl status &>/dev/null; then
|
|
49
|
+
return 0 # systemctl 无法使用,认为是 Docker
|
|
50
|
+
fi
|
|
51
|
+
|
|
37
52
|
return 1
|
|
38
53
|
}
|
|
39
54
|
|
|
@@ -41,6 +56,7 @@ is_docker() {
|
|
|
41
56
|
PORT="18789"
|
|
42
57
|
|
|
43
58
|
# 检查端口是否监听
|
|
59
|
+
# 注意:只检查端口,不检查进程。进程存在不等于端口在监听。
|
|
44
60
|
check_port() {
|
|
45
61
|
local port=$1
|
|
46
62
|
if command -v ss &>/dev/null; then
|
|
@@ -55,11 +71,9 @@ check_port() {
|
|
|
55
71
|
elif command -v fuser &>/dev/null; then
|
|
56
72
|
fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
|
|
57
73
|
return $?
|
|
58
|
-
else
|
|
59
|
-
# 最后降级:直接检查进程
|
|
60
|
-
[ -n "$(get_openclaw_pid)" ]
|
|
61
|
-
return $?
|
|
62
74
|
fi
|
|
75
|
+
# 如果所有工具都不可用,无法准确检查端口,保守返回 1(端口未监听)
|
|
76
|
+
return 1
|
|
63
77
|
}
|
|
64
78
|
|
|
65
79
|
# 获取 openclaw 进程 PID
|
|
@@ -192,15 +206,17 @@ stop_docker() {
|
|
|
192
206
|
|
|
193
207
|
log_info "发现 OpenClaw 进程: $all_pids"
|
|
194
208
|
|
|
195
|
-
#
|
|
196
|
-
log_info "
|
|
209
|
+
# 直接发送 SIGKILL(强制停止),避免 SIGTERM 被忽略
|
|
210
|
+
log_info "正在强制停止 OpenClaw 服务(SIGKILL)..."
|
|
197
211
|
for p in $all_pids; do
|
|
198
|
-
kill "$p"
|
|
212
|
+
kill -9 "$p" 2>/dev/null || true
|
|
199
213
|
done
|
|
214
|
+
# 额外使用 pkill 确保所有相关进程都被停止
|
|
215
|
+
pkill -9 -f "openclaw" 2>/dev/null || true
|
|
200
216
|
|
|
201
|
-
#
|
|
217
|
+
# 等待进程退出(最多 3 秒)
|
|
202
218
|
local elapsed=0
|
|
203
|
-
while [ $elapsed -lt
|
|
219
|
+
while [ $elapsed -lt 3 ]; do
|
|
204
220
|
# 检查是否还有 openclaw 进程
|
|
205
221
|
local remaining_pids=""
|
|
206
222
|
if command -v pgrep &>/dev/null; then
|
|
@@ -211,8 +227,8 @@ stop_docker() {
|
|
|
211
227
|
remaining_pids=$(ps aux | grep -v grep | grep "openclaw" | awk '{print $2}' | tr '\n' ' ')
|
|
212
228
|
fi
|
|
213
229
|
|
|
214
|
-
if [ -z "$remaining_pids" ]
|
|
215
|
-
log_info "OpenClaw
|
|
230
|
+
if [ -z "$remaining_pids" ]; then
|
|
231
|
+
log_info "OpenClaw 服务已停止。(所有进程已退出)"
|
|
216
232
|
log_info "服务已成功停止。"
|
|
217
233
|
log_info "Success"
|
|
218
234
|
exit 0
|
|
@@ -221,36 +237,13 @@ stop_docker() {
|
|
|
221
237
|
elapsed=$((elapsed + 1))
|
|
222
238
|
done
|
|
223
239
|
|
|
224
|
-
#
|
|
225
|
-
log_warn "
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
done
|
|
229
|
-
pkill -9 -f "openclaw" &>/dev/null || true
|
|
230
|
-
|
|
231
|
-
# 等待进程消失(最多 5 秒)
|
|
232
|
-
elapsed=0
|
|
233
|
-
while [ $elapsed -lt 5 ]; do
|
|
234
|
-
local remaining_pids=""
|
|
235
|
-
if command -v pgrep &>/dev/null; then
|
|
236
|
-
remaining_pids=$(pgrep -f "openclaw" | tr '\n' ' ')
|
|
237
|
-
elif command -v pidof &>/dev/null; then
|
|
238
|
-
remaining_pids=$(pidof openclaw)
|
|
239
|
-
else
|
|
240
|
-
remaining_pids=$(ps aux | grep -v grep | grep "openclaw" | awk '{print $2}' | tr '\n' ' ')
|
|
241
|
-
fi
|
|
242
|
-
|
|
243
|
-
if [ -z "$remaining_pids" ] && ! check_port "$PORT"; then
|
|
244
|
-
log_info "OpenClaw 服务已强制停止。"
|
|
245
|
-
log_info "服务已成功停止。"
|
|
246
|
-
log_info "Success"
|
|
247
|
-
exit 0
|
|
248
|
-
fi
|
|
249
|
-
sleep 1
|
|
250
|
-
elapsed=$((elapsed + 1))
|
|
251
|
-
done
|
|
240
|
+
# 如果进程仍在,再次强制停止
|
|
241
|
+
log_warn "进程仍在运行,再次强制停止..."
|
|
242
|
+
pkill -9 -f "openclaw" 2>/dev/null || true
|
|
243
|
+
killall -9 openclaw 2>/dev/null || true
|
|
252
244
|
|
|
253
|
-
#
|
|
245
|
+
# 最终检查
|
|
246
|
+
sleep 2
|
|
254
247
|
local remaining_pids=""
|
|
255
248
|
if command -v pgrep &>/dev/null; then
|
|
256
249
|
remaining_pids=$(pgrep -f "openclaw" | tr '\n' ' ')
|
|
@@ -260,16 +253,13 @@ stop_docker() {
|
|
|
260
253
|
remaining_pids=$(ps aux | grep -v grep | grep "openclaw" | awk '{print $2}' | tr '\n' ' ')
|
|
261
254
|
fi
|
|
262
255
|
|
|
263
|
-
if [ -z "$remaining_pids" ]
|
|
256
|
+
if [ -z "$remaining_pids" ]; then
|
|
264
257
|
log_info "OpenClaw 服务已停止。"
|
|
265
258
|
log_info "服务已成功停止。"
|
|
266
259
|
log_info "Success"
|
|
267
260
|
exit 0
|
|
268
|
-
elif [ -n "$remaining_pids" ]; then
|
|
269
|
-
log_error "OpenClaw 服务停止失败!进程仍然存在: $remaining_pids"
|
|
270
|
-
exit 1
|
|
271
261
|
else
|
|
272
|
-
log_error "OpenClaw
|
|
262
|
+
log_error "OpenClaw 服务停止失败!进程仍然存在: $remaining_pids"
|
|
273
263
|
exit 1
|
|
274
264
|
fi
|
|
275
265
|
}
|
package/package.json
CHANGED
|
@@ -136,33 +136,29 @@ async function verifyCommandResult(command, result, scriptOutput = '') {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
if (command === OpenClawCommandEnum.STOP) {
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
// 停止命令验证:多次检查端口,处理看门狗自动重启的情况
|
|
140
|
+
console.log(`[OpenClawControl] 开始验证停止结果...`);
|
|
141
|
+
|
|
142
|
+
let portStatus = 1;
|
|
143
|
+
let checkCount = 0;
|
|
144
|
+
const maxChecks = 5; // 最多检查 5 次
|
|
145
|
+
|
|
146
|
+
while (checkCount < maxChecks && portStatus === 1) {
|
|
147
|
+
await new Promise(resolve => setTimeout(resolve, 3000)); // 每次等待 3 秒
|
|
148
|
+
portStatus = await getOpenClawStatus(18789);
|
|
149
|
+
console.log(`[OpenClawControl] 停止验证第 ${checkCount + 1} 次检查,端口状态: ${portStatus}`);
|
|
150
|
+
checkCount++;
|
|
151
|
+
}
|
|
143
152
|
|
|
144
153
|
if (portStatus === 1) {
|
|
145
|
-
|
|
146
|
-
if (outputUpper.includes('SUCCESS') || outputUpper.includes('STOPPED')) {
|
|
147
|
-
console.warn(`[OpenClawControl] 警告: 端口仍在监听,但脚本报告成功。可能是僵尸进程或服务未正确停止。`);
|
|
148
|
-
// 仍然返回成功,但附带警告信息
|
|
149
|
-
return {
|
|
150
|
-
status: result.status,
|
|
151
|
-
message: result.message + ' (警告: 端口仍在监听)'
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
+
console.error(`[OpenClawControl] 停止失败: 经过 ${maxChecks} 次检查,端口 18789 仍在监听。服务可能被看门狗自动重启。`);
|
|
154
155
|
return {
|
|
155
156
|
status: OpenClawServiceStatus.ERROR,
|
|
156
|
-
message: '停止失败:
|
|
157
|
-
};
|
|
158
|
-
} else if (portStatus === 2) {
|
|
159
|
-
// 进程存在但端口未监听,可能服务正在停止中
|
|
160
|
-
console.warn(`[OpenClawControl] 警告: openclaw 进程仍存在但端口已关闭。`);
|
|
161
|
-
return {
|
|
162
|
-
status: result.status,
|
|
163
|
-
message: result.message + ' (警告: 进程仍存在)'
|
|
157
|
+
message: '停止失败: 服务仍在运行(可能被自动重启)'
|
|
164
158
|
};
|
|
165
159
|
}
|
|
160
|
+
|
|
161
|
+
console.log(`[OpenClawControl] 停止验证通过: 端口已关闭`);
|
|
166
162
|
} else if (command === OpenClawCommandEnum.START || command === OpenClawCommandEnum.RESTART) {
|
|
167
163
|
// 等待服务启动
|
|
168
164
|
const maxWait = command === OpenClawCommandEnum.START ? 30 : 60;
|
|
@@ -314,9 +314,12 @@ class ScriptExecutor {
|
|
|
314
314
|
if (upper.includes(kw.toUpperCase())) return true;
|
|
315
315
|
}
|
|
316
316
|
|
|
317
|
-
// 对于 START
|
|
318
|
-
//
|
|
319
|
-
|
|
317
|
+
// 对于 START/STOP/RESTART 命令,不提前返回
|
|
318
|
+
// 让脚本完整执行到 exit,由 exit code 判断成功失败
|
|
319
|
+
// 提前返回可能导致 kill 命令未执行完成
|
|
320
|
+
if (command === OpenClawCommandEnum.START ||
|
|
321
|
+
command === OpenClawCommandEnum.STOP ||
|
|
322
|
+
command === OpenClawCommandEnum.RESTART) {
|
|
320
323
|
return false;
|
|
321
324
|
}
|
|
322
325
|
|