claw-subagent-service 0.0.87 → 0.0.88

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.
@@ -34,6 +34,7 @@ get_openclaw_pid() {
34
34
  local pid=""
35
35
 
36
36
  # 按优先级尝试多种工具(适配精简 Docker 镜像)
37
+ # 方法1: lsof(最可靠)
37
38
  if command -v lsof &>/dev/null; then
38
39
  pid=$(lsof -i :${port} -t 2>/dev/null | head -1)
39
40
  if [ -n "$pid" ]; then
@@ -42,6 +43,7 @@ get_openclaw_pid() {
42
43
  fi
43
44
  fi
44
45
 
46
+ # 方法2: fuser
45
47
  if command -v fuser &>/dev/null; then
46
48
  pid=$(fuser ${port}/tcp 2>/dev/null | tr -d ' ')
47
49
  if [ -n "$pid" ]; then
@@ -50,14 +52,16 @@ get_openclaw_pid() {
50
52
  fi
51
53
  fi
52
54
 
55
+ # 方法3: ss
53
56
  if command -v ss &>/dev/null; then
54
- pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\\([0-9]*\\).*/\\1/p')
57
+ pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
55
58
  if [ -n "$pid" ]; then
56
59
  echo "$pid"
57
60
  return
58
61
  fi
59
62
  fi
60
63
 
64
+ # 方法4: netstat
61
65
  if command -v netstat &>/dev/null; then
62
66
  pid=$(netstat -tnlp 2>/dev/null | grep ":${port} " | head -1 | awk '{print $7}' | cut -d'/' -f1)
63
67
  if [ -n "$pid" ]; then
@@ -66,19 +70,16 @@ get_openclaw_pid() {
66
70
  fi
67
71
  fi
68
72
 
69
- # 最后尝试 /proc 文件系统(最可靠,无需外部工具)
73
+ # 方法5: 通过 /proc/net/tcp 查找(不需要外部工具,最可靠)
74
+ # 端口 18789 的十六进制 = 0x4965
75
+ local hex_port="4965"
70
76
  for proc_dir in /proc/[0-9]*; do
71
- if [ -d "$proc_dir/fd" ]; then
72
- for fd in $proc_dir/fd/*; do
73
- if [ -L "$fd" ]; then
74
- local target
75
- target=$(readlink "$fd" 2>/dev/null)
76
- if [ -n "$target" ] && echo "$target" | grep -q ":${port}"; then
77
- basename "$proc_dir"
78
- return
79
- fi
80
- fi
81
- done
77
+ if [ -f "$proc_dir/net/tcp" ]; then
78
+ # 检查该进程是否监听目标端口
79
+ if grep -q "[^0-9a-fA-F]${hex_port} " "$proc_dir/net/tcp" 2>/dev/null; then
80
+ basename "$proc_dir"
81
+ return
82
+ fi
82
83
  fi
83
84
  done
84
85
 
@@ -146,25 +147,41 @@ restart_docker() {
146
147
  fi
147
148
 
148
149
  # 如果正在运行,先停止
149
- if [ -n "$pid" ]; then
150
+ if [ -n "$pid" ] || check_port "$PORT"; then
150
151
  log_info "正在停止 OpenClaw 服务..."
151
- kill "$pid" &>/dev/null || true
152
+ if [ -n "$pid" ]; then
153
+ kill "$pid" &>/dev/null || true
154
+ fi
152
155
 
153
- # 等待停止(最多 5 秒)
156
+ # 等待停止(最多 10 秒),使用端口双重验证
154
157
  local elapsed=0
155
- while [ $elapsed -lt 5 ]; do
156
- if [ -z "$(get_openclaw_pid)" ]; then
158
+ while [ $elapsed -lt 10 ]; do
159
+ local current_pid
160
+ current_pid=$(get_openclaw_pid)
161
+ if [ -z "$current_pid" ] && ! check_port "$PORT"; then
157
162
  break
158
163
  fi
159
164
  sleep 1
160
165
  elapsed=$((elapsed + 1))
161
166
  done
162
167
 
163
- # 如果还在运行,强制停止
164
- if [ -n "$(get_openclaw_pid)" ]; then
165
- log_warn "服务未在 5 秒内停止,正在强制停止..."
166
- kill -9 "$pid" &>/dev/null || true
167
- sleep 1
168
+ # 如果还在运行,强制停止并使用备选方案
169
+ if check_port "$PORT"; then
170
+ log_warn "服务未在 10 秒内停止,正在强制停止..."
171
+ if [ -n "$pid" ]; then
172
+ kill -9 "$pid" &>/dev/null || true
173
+ fi
174
+ pkill -9 -f "openclaw" &>/dev/null || true
175
+ if command -v fuser &>/dev/null; then
176
+ fuser -k "${PORT}/tcp" &>/dev/null || true
177
+ fi
178
+ sleep 2
179
+
180
+ # 最终验证
181
+ if check_port "$PORT"; then
182
+ log_error "OpenClaw 服务停止失败!端口 $PORT 仍在监听。"
183
+ exit 1
184
+ fi
168
185
  fi
169
186
 
170
187
  log_info "服务已停止"
@@ -34,6 +34,7 @@ get_openclaw_pid() {
34
34
  local pid=""
35
35
 
36
36
  # 按优先级尝试多种工具(适配精简 Docker 镜像)
37
+ # 方法1: lsof(最可靠)
37
38
  if command -v lsof &>/dev/null; then
38
39
  pid=$(lsof -i :${port} -t 2>/dev/null | head -1)
39
40
  if [ -n "$pid" ]; then
@@ -42,6 +43,7 @@ get_openclaw_pid() {
42
43
  fi
43
44
  fi
44
45
 
46
+ # 方法2: fuser
45
47
  if command -v fuser &>/dev/null; then
46
48
  pid=$(fuser ${port}/tcp 2>/dev/null | tr -d ' ')
47
49
  if [ -n "$pid" ]; then
@@ -50,14 +52,16 @@ get_openclaw_pid() {
50
52
  fi
51
53
  fi
52
54
 
55
+ # 方法3: ss
53
56
  if command -v ss &>/dev/null; then
54
- pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\\([0-9]*\\).*/\\1/p')
57
+ pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
55
58
  if [ -n "$pid" ]; then
56
59
  echo "$pid"
57
60
  return
58
61
  fi
59
62
  fi
60
63
 
64
+ # 方法4: netstat
61
65
  if command -v netstat &>/dev/null; then
62
66
  pid=$(netstat -tnlp 2>/dev/null | grep ":${port} " | head -1 | awk '{print $7}' | cut -d'/' -f1)
63
67
  if [ -n "$pid" ]; then
@@ -66,19 +70,16 @@ get_openclaw_pid() {
66
70
  fi
67
71
  fi
68
72
 
69
- # 最后尝试 /proc 文件系统(最可靠,无需外部工具)
73
+ # 方法5: 通过 /proc/net/tcp 查找(不需要外部工具,最可靠)
74
+ # 端口 18789 的十六进制 = 0x4965
75
+ local hex_port="4965"
70
76
  for proc_dir in /proc/[0-9]*; do
71
- if [ -d "$proc_dir/fd" ]; then
72
- for fd in $proc_dir/fd/*; do
73
- if [ -L "$fd" ]; then
74
- local target
75
- target=$(readlink "$fd" 2>/dev/null)
76
- if [ -n "$target" ] && echo "$target" | grep -q ":${port}"; then
77
- basename "$proc_dir"
78
- return
79
- fi
80
- fi
81
- done
77
+ if [ -f "$proc_dir/net/tcp" ]; then
78
+ # 检查该进程是否监听目标端口
79
+ if grep -q "[^0-9a-fA-F]${hex_port} " "$proc_dir/net/tcp" 2>/dev/null; then
80
+ basename "$proc_dir"
81
+ return
82
+ fi
82
83
  fi
83
84
  done
84
85
 
@@ -48,6 +48,7 @@ get_openclaw_pid() {
48
48
  local pid=""
49
49
 
50
50
  # 按优先级尝试多种工具(适配精简 Docker 镜像)
51
+ # 方法1: lsof(最可靠)
51
52
  if command -v lsof &>/dev/null; then
52
53
  pid=$(lsof -i :${port} -t 2>/dev/null | head -1)
53
54
  if [ -n "$pid" ]; then
@@ -56,6 +57,7 @@ get_openclaw_pid() {
56
57
  fi
57
58
  fi
58
59
 
60
+ # 方法2: fuser
59
61
  if command -v fuser &>/dev/null; then
60
62
  pid=$(fuser ${port}/tcp 2>/dev/null | tr -d ' ')
61
63
  if [ -n "$pid" ]; then
@@ -64,6 +66,7 @@ get_openclaw_pid() {
64
66
  fi
65
67
  fi
66
68
 
69
+ # 方法3: ss
67
70
  if command -v ss &>/dev/null; then
68
71
  pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
69
72
  if [ -n "$pid" ]; then
@@ -72,6 +75,7 @@ get_openclaw_pid() {
72
75
  fi
73
76
  fi
74
77
 
78
+ # 方法4: netstat
75
79
  if command -v netstat &>/dev/null; then
76
80
  pid=$(netstat -tnlp 2>/dev/null | grep ":${port} " | head -1 | awk '{print $7}' | cut -d'/' -f1)
77
81
  if [ -n "$pid" ]; then
@@ -80,19 +84,16 @@ get_openclaw_pid() {
80
84
  fi
81
85
  fi
82
86
 
83
- # 最后尝试 /proc 文件系统(最可靠,无需外部工具)
87
+ # 方法5: 通过 /proc/net/tcp 查找(不需要外部工具,最可靠)
88
+ # 端口 18789 的十六进制 = 0x4965
89
+ local hex_port="4965"
84
90
  for proc_dir in /proc/[0-9]*; do
85
- if [ -d "$proc_dir/fd" ]; then
86
- for fd in $proc_dir/fd/*; do
87
- if [ -L "$fd" ]; then
88
- local target
89
- target=$(readlink "$fd" 2>/dev/null)
90
- if [ -n "$target" ] && echo "$target" | grep -q ":${port}"; then
91
- basename "$proc_dir"
92
- return
93
- fi
94
- fi
95
- done
91
+ if [ -f "$proc_dir/net/tcp" ]; then
92
+ # 检查该进程是否监听目标端口
93
+ if grep -q "[^0-9a-fA-F]${hex_port} " "$proc_dir/net/tcp" 2>/dev/null; then
94
+ basename "$proc_dir"
95
+ return
96
+ fi
96
97
  fi
97
98
  done
98
99
 
@@ -67,6 +67,7 @@ get_openclaw_pid() {
67
67
  local pid=""
68
68
 
69
69
  # 按优先级尝试多种工具(适配精简 Docker 镜像)
70
+ # 方法1: lsof(最可靠)
70
71
  if command -v lsof &>/dev/null; then
71
72
  pid=$(lsof -i :${port} -t 2>/dev/null | head -1)
72
73
  if [ -n "$pid" ]; then
@@ -75,6 +76,7 @@ get_openclaw_pid() {
75
76
  fi
76
77
  fi
77
78
 
79
+ # 方法2: fuser
78
80
  if command -v fuser &>/dev/null; then
79
81
  pid=$(fuser ${port}/tcp 2>/dev/null | tr -d ' ')
80
82
  if [ -n "$pid" ]; then
@@ -83,14 +85,16 @@ get_openclaw_pid() {
83
85
  fi
84
86
  fi
85
87
 
88
+ # 方法3: ss
86
89
  if command -v ss &>/dev/null; then
87
- pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\\([0-9]*\\).*/\\1/p')
90
+ pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
88
91
  if [ -n "$pid" ]; then
89
92
  echo "$pid"
90
93
  return
91
94
  fi
92
95
  fi
93
96
 
97
+ # 方法4: netstat
94
98
  if command -v netstat &>/dev/null; then
95
99
  pid=$(netstat -tnlp 2>/dev/null | grep ":${port} " | head -1 | awk '{print $7}' | cut -d'/' -f1)
96
100
  if [ -n "$pid" ]; then
@@ -99,19 +103,16 @@ get_openclaw_pid() {
99
103
  fi
100
104
  fi
101
105
 
102
- # 最后尝试 /proc 文件系统(最可靠,无需外部工具)
106
+ # 方法5: 通过 /proc/net/tcp 查找(不需要外部工具,最可靠)
107
+ # 端口 18789 的十六进制 = 0x4965
108
+ local hex_port="4965"
103
109
  for proc_dir in /proc/[0-9]*; do
104
- if [ -d "$proc_dir/fd" ]; then
105
- for fd in $proc_dir/fd/*; do
106
- if [ -L "$fd" ]; then
107
- local target
108
- target=$(readlink "$fd" 2>/dev/null)
109
- if [ -n "$target" ] && echo "$target" | grep -q ":${port}"; then
110
- basename "$proc_dir"
111
- return
112
- fi
113
- fi
114
- done
110
+ if [ -f "$proc_dir/net/tcp" ]; then
111
+ # 检查该进程是否监听目标端口
112
+ if grep -q "[^0-9a-fA-F]${hex_port} " "$proc_dir/net/tcp" 2>/dev/null; then
113
+ basename "$proc_dir"
114
+ return
115
+ fi
115
116
  fi
116
117
  done
117
118
 
@@ -126,6 +127,32 @@ stop_docker() {
126
127
  # 检查服务状态
127
128
  log_info "检查 OpenClaw 服务状态..."
128
129
  if [ -z "$pid" ]; then
130
+ # 即使找不到 PID,也检查端口是否还在监听
131
+ if check_port "$PORT"; then
132
+ log_warn "端口 $PORT 仍在监听,但无法获取 PID,尝试备选停止方案..."
133
+ # 尝试通过 fuser 直接通过端口杀进程
134
+ if command -v fuser &>/dev/null; then
135
+ log_info "使用 fuser 通过端口停止服务..."
136
+ fuser -k "${PORT}/tcp" &>/dev/null || true
137
+ sleep 2
138
+ fi
139
+ # 尝试通过 pkill 停止 openclaw 相关进程
140
+ if check_port "$PORT"; then
141
+ log_info "使用 pkill 停止 openclaw 进程..."
142
+ pkill -f "openclaw" &>/dev/null || true
143
+ sleep 2
144
+ fi
145
+ # 最终验证
146
+ if ! check_port "$PORT"; then
147
+ log_info "OpenClaw 服务已停止(通过备选方案)。"
148
+ log_info "服务已成功停止。"
149
+ log_info "Success"
150
+ exit 0
151
+ else
152
+ log_error "OpenClaw 服务停止失败!所有停止方案均无效。"
153
+ exit 1
154
+ fi
155
+ fi
129
156
  log_warn "OpenClaw 服务未在运行。"
130
157
  exit 0
131
158
  fi
@@ -133,14 +160,17 @@ stop_docker() {
133
160
  log_info "OpenClaw 服务正在运行(PID: $pid),准备停止..."
134
161
 
135
162
  # 停止服务:先发送 SIGTERM(优雅停止)
136
- log_info "正在停止 OpenClaw 服务..."
163
+ log_info "正在停止 OpenClaw 服务(发送 SIGTERM)..."
137
164
  kill "$pid" &>/dev/null || true
138
165
 
139
- # 等待服务完全停止(最多 10 秒)
166
+ # 等待服务完全停止(最多 10 秒),使用端口双重验证
140
167
  local elapsed=0
141
168
  while [ $elapsed -lt 10 ]; do
142
- if [ -z "$(get_openclaw_pid)" ]; then
143
- log_info "OpenClaw 服务停止成功!"
169
+ # 双重验证:检查 PID 和端口
170
+ local current_pid
171
+ current_pid=$(get_openclaw_pid)
172
+ if [ -z "$current_pid" ] && ! check_port "$PORT"; then
173
+ log_info "OpenClaw 服务停止成功!(PID 和端口均已关闭)"
144
174
  log_info "服务已成功停止。"
145
175
  log_info "Success"
146
176
  exit 0
@@ -153,32 +183,38 @@ stop_docker() {
153
183
  log_warn "服务未在 10 秒内停止,正在强制停止..."
154
184
  kill -9 "$pid" &>/dev/null || true
155
185
 
156
- # 等待进程消失(最多 3 秒)
186
+ # 额外:尝试 pkill 确保所有相关进程都被停止
187
+ pkill -9 -f "openclaw" &>/dev/null || true
188
+
189
+ # 等待进程消失(最多 5 秒)
157
190
  elapsed=0
158
- while [ $elapsed -lt 3 ]; do
159
- if [ -z "$(get_openclaw_pid)" ]; then
160
- break
191
+ while [ $elapsed -lt 5 ]; do
192
+ local current_pid
193
+ current_pid=$(get_openclaw_pid)
194
+ if [ -z "$current_pid" ] && ! check_port "$PORT"; then
195
+ log_info "OpenClaw 服务已强制停止。"
196
+ log_info "服务已成功停止。"
197
+ log_info "Success"
198
+ exit 0
161
199
  fi
162
200
  sleep 1
163
201
  elapsed=$((elapsed + 1))
164
202
  done
165
203
 
166
- # 验证:进程不存在或端口已关闭即为成功
167
- # 使用端口检测作为辅助,避免僵尸进程导致误判
204
+ # 最终验证
168
205
  local current_pid
169
206
  current_pid=$(get_openclaw_pid)
170
- if [ -z "$current_pid" ]; then
171
- log_info "OpenClaw 服务已强制停止。"
207
+ if [ -z "$current_pid" ] && ! check_port "$PORT"; then
208
+ log_info "OpenClaw 服务已停止。"
172
209
  log_info "服务已成功停止。"
173
210
  log_info "Success"
174
- elif ! check_port "$PORT"; then
175
- # 端口已关闭但进程可能还在(僵尸状态),也认为成功
211
+ elif check_port "$PORT"; then
212
+ log_error "OpenClaw 服务停止失败!端口 $PORT 仍在监听。"
213
+ exit 1
214
+ else
176
215
  log_info "OpenClaw 服务已停止(端口已关闭)。"
177
216
  log_info "服务已成功停止。"
178
217
  log_info "Success"
179
- else
180
- log_error "OpenClaw 服务停止失败!进程仍然存在且端口仍在监听。"
181
- exit 1
182
218
  fi
183
219
  }
184
220
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claw-subagent-service",
3
- "version": "0.0.87",
3
+ "version": "0.0.88",
4
4
  "description": "虾说智能助手",
5
5
  "main": "cli.js",
6
6
  "bin": {