claw-subagent-service 0.0.93 → 0.0.95

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.
@@ -4,7 +4,8 @@
4
4
  # 用法: ./restart.sh [选项]
5
5
  # 支持 systemd 和 Docker(无 systemd)双模式
6
6
 
7
- set -e
7
+ # 注意:不使用 set -e,因为我们已经实现了完善的错误处理和验证逻辑
8
+ # set -e 可能导致 pgrep/pidof 找不到进程时脚本意外退出
8
9
 
9
10
  # 颜色定义
10
11
  RED='\033[0;31m'
@@ -21,10 +22,24 @@ MAX_WAIT=300 # 最长等待5分钟
21
22
  PORT="18789"
22
23
 
23
24
  # 检测是否在 Docker 环境(无 systemd)
25
+ # 注意:某些 Docker 镜像安装了 systemctl 命令但无法使用
26
+ # 所以同时检查 systemd 是否实际运行
24
27
  is_docker() {
28
+ # 方法1: 检查 systemctl 是否可用
25
29
  if ! command -v systemctl &>/dev/null; then
26
30
  return 0 # 无 systemctl,认为是 Docker
27
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
+
28
43
  return 1
29
44
  }
30
45
 
@@ -111,6 +126,7 @@ get_openclaw_pid() {
111
126
  }
112
127
 
113
128
  # 检查端口是否监听
129
+ # 注意:只检查端口,不检查进程。进程存在不等于端口在监听。
114
130
  check_port() {
115
131
  local port=$1
116
132
  if command -v ss &>/dev/null; then
@@ -125,11 +141,9 @@ check_port() {
125
141
  elif command -v fuser &>/dev/null; then
126
142
  fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
127
143
  return $?
128
- else
129
- # 降级:直接检查进程
130
- [ -n "$(get_openclaw_pid)" ]
131
- return $?
132
144
  fi
145
+ # 如果所有工具都不可用,无法准确检查端口,保守返回 1(端口未监听)
146
+ return 1
133
147
  }
134
148
 
135
149
  # 等待端口启动
@@ -4,7 +4,8 @@
4
4
  # 用法: ./start.sh [选项]
5
5
  # 支持 systemd 和 Docker(无 systemd)双模式
6
6
 
7
- set -e
7
+ # 注意:不使用 set -e,因为我们已经实现了完善的错误处理和验证逻辑
8
+ # set -e 可能导致 pgrep/pidof 找不到进程时脚本意外退出
8
9
 
9
10
  # 颜色定义
10
11
  RED='\033[0;31m'
@@ -21,10 +22,24 @@ MAX_WAIT=300 # 最长等待5分钟
21
22
  PORT="18789"
22
23
 
23
24
  # 检测是否在 Docker 环境(无 systemd)
25
+ # 注意:某些 Docker 镜像安装了 systemctl 命令但无法使用
26
+ # 所以同时检查 systemd 是否实际运行
24
27
  is_docker() {
28
+ # 方法1: 检查 systemctl 是否可用
25
29
  if ! command -v systemctl &>/dev/null; then
26
30
  return 0 # 无 systemctl,认为是 Docker
27
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
+
28
43
  return 1
29
44
  }
30
45
 
@@ -111,6 +126,7 @@ get_openclaw_pid() {
111
126
  }
112
127
 
113
128
  # 检查端口是否监听
129
+ # 注意:只检查端口,不检查进程。进程存在不等于端口在监听。
114
130
  check_port() {
115
131
  local port=$1
116
132
  if command -v ss &>/dev/null; then
@@ -125,11 +141,9 @@ check_port() {
125
141
  elif command -v fuser &>/dev/null; then
126
142
  fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
127
143
  return $?
128
- else
129
- # 降级:直接检查进程
130
- [ -n "$(get_openclaw_pid)" ]
131
- return $?
132
144
  fi
145
+ # 如果所有工具都不可用,无法准确检查端口,保守返回 1(端口未监听)
146
+ return 1
133
147
  }
134
148
 
135
149
  # 等待端口启动
@@ -4,7 +4,8 @@
4
4
  # 用法: ./status.sh [选项]
5
5
  # 支持 systemd 和 Docker(无 systemd)双模式
6
6
 
7
- set -e
7
+ # 注意:不使用 set -e,因为我们已经实现了完善的错误处理和验证逻辑
8
+ # set -e 可能导致 pgrep/pidof 找不到进程时脚本意外退出
8
9
 
9
10
  # 颜色定义
10
11
  RED='\033[0;31m'
@@ -35,10 +36,24 @@ SERVICE_NAME="openclaw-gateway.service"
35
36
  PORT="18789"
36
37
 
37
38
  # 检测是否在 Docker 环境(无 systemd)
39
+ # 注意:某些 Docker 镜像安装了 systemctl 命令但无法使用
40
+ # 所以同时检查 systemd 是否实际运行
38
41
  is_docker() {
42
+ # 方法1: 检查 systemctl 是否可用
39
43
  if ! command -v systemctl &>/dev/null; then
40
44
  return 0 # 无 systemctl,认为是 Docker
41
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
+
42
57
  return 1
43
58
  }
44
59
 
@@ -125,6 +140,7 @@ get_openclaw_pid() {
125
140
  }
126
141
 
127
142
  # 检查端口是否监听
143
+ # 注意:只检查端口,不检查进程。进程存在不等于端口在监听。
128
144
  check_port() {
129
145
  local port=$1
130
146
  if command -v ss &>/dev/null; then
@@ -139,11 +155,9 @@ check_port() {
139
155
  elif command -v fuser &>/dev/null; then
140
156
  fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
141
157
  return $?
142
- else
143
- # 降级:直接检查进程
144
- [ -n "$(get_openclaw_pid)" ]
145
- return $?
146
158
  fi
159
+ # 如果所有工具都不可用,无法准确检查端口,保守返回 1(端口未监听)
160
+ return 1
147
161
  }
148
162
 
149
163
  # Docker 模式:查看状态
@@ -4,7 +4,8 @@
4
4
  # 用法: ./stop.sh [选项]
5
5
  # 支持 systemd 和 Docker(无 systemd)双模式
6
6
 
7
- set -e
7
+ # 注意:不使用 set -e,因为我们已经实现了完善的错误处理和验证逻辑
8
+ # set -e 可能导致 pgrep/pidof 找不到进程时脚本意外退出
8
9
 
9
10
  # 颜色定义
10
11
  RED='\033[0;31m'
@@ -29,10 +30,25 @@ log_error() {
29
30
  SERVICE_NAME="openclaw-gateway.service"
30
31
 
31
32
  # 检测是否在 Docker 环境(无 systemd)
33
+ # 注意:某些 Docker 镜像安装了 systemctl 命令但无法使用
34
+ # 所以同时检查 systemd 是否实际运行
32
35
  is_docker() {
36
+ # 方法1: 检查 systemctl 是否可用
33
37
  if ! command -v systemctl &>/dev/null; then
34
38
  return 0 # 无 systemctl,认为是 Docker
35
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
+
36
52
  return 1
37
53
  }
38
54
 
@@ -40,6 +56,7 @@ is_docker() {
40
56
  PORT="18789"
41
57
 
42
58
  # 检查端口是否监听
59
+ # 注意:只检查端口,不检查进程。进程存在不等于端口在监听。
43
60
  check_port() {
44
61
  local port=$1
45
62
  if command -v ss &>/dev/null; then
@@ -54,11 +71,9 @@ check_port() {
54
71
  elif command -v fuser &>/dev/null; then
55
72
  fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
56
73
  return $?
57
- else
58
- # 最后降级:直接检查进程
59
- [ -n "$(get_openclaw_pid)" ]
60
- return $?
61
74
  fi
75
+ # 如果所有工具都不可用,无法准确检查端口,保守返回 1(端口未监听)
76
+ return 1
62
77
  }
63
78
 
64
79
  # 获取 openclaw 进程 PID
@@ -146,13 +161,24 @@ get_openclaw_pid() {
146
161
 
147
162
  # Docker 模式:停止服务
148
163
  stop_docker() {
164
+ log_info "检查 OpenClaw 服务状态..."
165
+
166
+ # 获取所有 openclaw 进程 PID
167
+ local all_pids=""
168
+ if command -v pgrep &>/dev/null; then
169
+ all_pids=$(pgrep -f "openclaw" | tr '\n' ' ')
170
+ elif command -v pidof &>/dev/null; then
171
+ all_pids=$(pidof openclaw)
172
+ else
173
+ all_pids=$(ps aux | grep -v grep | grep "openclaw" | awk '{print $2}' | tr '\n' ' ')
174
+ fi
175
+
149
176
  local pid
150
177
  pid=$(get_openclaw_pid)
151
178
 
152
179
  # 检查服务状态
153
- log_info "检查 OpenClaw 服务状态..."
154
- if [ -z "$pid" ]; then
155
- # 即使找不到 PID,也检查端口是否还在监听
180
+ if [ -z "$pid" ] && [ -z "$all_pids" ]; then
181
+ # 没有进程,检查端口
156
182
  if check_port "$PORT"; then
157
183
  log_warn "端口 $PORT 仍在监听,但无法获取 PID,尝试备选停止方案..."
158
184
  # 尝试通过 fuser 直接通过端口杀进程
@@ -164,38 +190,43 @@ stop_docker() {
164
190
  # 尝试通过 pkill 停止 openclaw 相关进程
165
191
  if check_port "$PORT"; then
166
192
  log_info "使用 pkill 停止 openclaw 进程..."
167
- pkill -f "openclaw" &>/dev/null || true
193
+ pkill -9 -f "openclaw" &>/dev/null || true
168
194
  sleep 2
169
195
  fi
170
- # 最终验证
171
- if ! check_port "$PORT"; then
172
- log_info "OpenClaw 服务已停止(通过备选方案)。"
173
- log_info "服务已成功停止。"
174
- log_info "Success"
175
- exit 0
176
- else
177
- log_error "OpenClaw 服务停止失败!所有停止方案均无效。"
178
- exit 1
179
- fi
180
196
  fi
181
- log_warn "OpenClaw 服务未在运行。"
182
- exit 0
197
+
198
+ if ! check_port "$PORT" && [ -z "$(ps aux | grep -v grep | grep 'openclaw' | awk '{print $2}')" ]; then
199
+ log_warn "OpenClaw 服务未在运行。"
200
+ exit 0
201
+ else
202
+ log_error "OpenClaw 服务停止失败!"
203
+ exit 1
204
+ fi
183
205
  fi
184
206
 
185
- log_info "OpenClaw 服务正在运行(PID: $pid),准备停止..."
207
+ log_info "发现 OpenClaw 进程: $all_pids"
186
208
 
187
- # 停止服务:先发送 SIGTERM(优雅停止)
209
+ # 停止所有 openclaw 进程:先发送 SIGTERM(优雅停止)
188
210
  log_info "正在停止 OpenClaw 服务(发送 SIGTERM)..."
189
- kill "$pid" &>/dev/null || true
211
+ for p in $all_pids; do
212
+ kill "$p" &>/dev/null || true
213
+ done
190
214
 
191
- # 等待服务完全停止(最多 10 秒),使用端口双重验证
215
+ # 等待服务完全停止(最多 10 秒)
192
216
  local elapsed=0
193
217
  while [ $elapsed -lt 10 ]; do
194
- # 双重验证:检查 PID 和端口
195
- local current_pid
196
- current_pid=$(get_openclaw_pid)
197
- if [ -z "$current_pid" ] && ! check_port "$PORT"; then
198
- log_info "OpenClaw 服务停止成功!(PID 和端口均已关闭)"
218
+ # 检查是否还有 openclaw 进程
219
+ local remaining_pids=""
220
+ if command -v pgrep &>/dev/null; then
221
+ remaining_pids=$(pgrep -f "openclaw" | tr '\n' ' ')
222
+ elif command -v pidof &>/dev/null; then
223
+ remaining_pids=$(pidof openclaw)
224
+ else
225
+ remaining_pids=$(ps aux | grep -v grep | grep "openclaw" | awk '{print $2}' | tr '\n' ' ')
226
+ fi
227
+
228
+ if [ -z "$remaining_pids" ] && ! check_port "$PORT"; then
229
+ log_info "OpenClaw 服务停止成功!(所有进程已退出,端口已关闭)"
199
230
  log_info "服务已成功停止。"
200
231
  log_info "Success"
201
232
  exit 0
@@ -206,17 +237,24 @@ stop_docker() {
206
237
 
207
238
  # 如果还在运行,强制停止(SIGKILL)
208
239
  log_warn "服务未在 10 秒内停止,正在强制停止..."
209
- kill -9 "$pid" &>/dev/null || true
210
-
211
- # 额外:尝试 pkill 确保所有相关进程都被停止
240
+ for p in $all_pids; do
241
+ kill -9 "$p" &>/dev/null || true
242
+ done
212
243
  pkill -9 -f "openclaw" &>/dev/null || true
213
244
 
214
245
  # 等待进程消失(最多 5 秒)
215
246
  elapsed=0
216
247
  while [ $elapsed -lt 5 ]; do
217
- local current_pid
218
- current_pid=$(get_openclaw_pid)
219
- if [ -z "$current_pid" ] && ! check_port "$PORT"; then
248
+ local remaining_pids=""
249
+ if command -v pgrep &>/dev/null; then
250
+ remaining_pids=$(pgrep -f "openclaw" | tr '\n' ' ')
251
+ elif command -v pidof &>/dev/null; then
252
+ remaining_pids=$(pidof openclaw)
253
+ else
254
+ remaining_pids=$(ps aux | grep -v grep | grep "openclaw" | awk '{print $2}' | tr '\n' ' ')
255
+ fi
256
+
257
+ if [ -z "$remaining_pids" ] && ! check_port "$PORT"; then
220
258
  log_info "OpenClaw 服务已强制停止。"
221
259
  log_info "服务已成功停止。"
222
260
  log_info "Success"
@@ -227,21 +265,26 @@ stop_docker() {
227
265
  done
228
266
 
229
267
  # 最终验证
230
- local current_pid
231
- current_pid=$(get_openclaw_pid)
232
- if [ -z "$current_pid" ] && ! check_port "$PORT"; then
268
+ local remaining_pids=""
269
+ if command -v pgrep &>/dev/null; then
270
+ remaining_pids=$(pgrep -f "openclaw" | tr '\n' ' ')
271
+ elif command -v pidof &>/dev/null; then
272
+ remaining_pids=$(pidof openclaw)
273
+ else
274
+ remaining_pids=$(ps aux | grep -v grep | grep "openclaw" | awk '{print $2}' | tr '\n' ' ')
275
+ fi
276
+
277
+ if [ -z "$remaining_pids" ] && ! check_port "$PORT"; then
233
278
  log_info "OpenClaw 服务已停止。"
234
279
  log_info "服务已成功停止。"
235
280
  log_info "Success"
236
281
  exit 0
237
- elif check_port "$PORT"; then
238
- log_error "OpenClaw 服务停止失败!端口 $PORT 仍在监听。"
282
+ elif [ -n "$remaining_pids" ]; then
283
+ log_error "OpenClaw 服务停止失败!进程仍然存在: $remaining_pids"
239
284
  exit 1
240
285
  else
241
- log_info "OpenClaw 服务已停止(端口已关闭)。"
242
- log_info "服务已成功停止。"
243
- log_info "Success"
244
- exit 0
286
+ log_error "OpenClaw 服务停止失败!端口 $PORT 仍在监听。"
287
+ exit 1
245
288
  fi
246
289
  }
247
290
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claw-subagent-service",
3
- "version": "0.0.93",
3
+ "version": "0.0.95",
4
4
  "description": "虾说智能助手",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -314,9 +314,12 @@ class ScriptExecutor {
314
314
  if (upper.includes(kw.toUpperCase())) return true;
315
315
  }
316
316
 
317
- // 对于 START 命令,不提前返回,让脚本完整执行
318
- // 因为 start.bat 有等待循环,需要完整输出才能判断状态
319
- if (command === OpenClawCommandEnum.START) {
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