claw-subagent-service 0.0.86 → 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.
package/command/linux/restart.sh
CHANGED
|
@@ -30,17 +30,59 @@ is_docker() {
|
|
|
30
30
|
|
|
31
31
|
# 获取 openclaw 进程 PID
|
|
32
32
|
get_openclaw_pid() {
|
|
33
|
-
|
|
33
|
+
local port=18789
|
|
34
|
+
local pid=""
|
|
35
|
+
|
|
36
|
+
# 按优先级尝试多种工具(适配精简 Docker 镜像)
|
|
37
|
+
# 方法1: lsof(最可靠)
|
|
38
|
+
if command -v lsof &>/dev/null; then
|
|
39
|
+
pid=$(lsof -i :${port} -t 2>/dev/null | head -1)
|
|
40
|
+
if [ -n "$pid" ]; then
|
|
41
|
+
echo "$pid"
|
|
42
|
+
return
|
|
43
|
+
fi
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# 方法2: fuser
|
|
47
|
+
if command -v fuser &>/dev/null; then
|
|
48
|
+
pid=$(fuser ${port}/tcp 2>/dev/null | tr -d ' ')
|
|
49
|
+
if [ -n "$pid" ]; then
|
|
50
|
+
echo "$pid"
|
|
51
|
+
return
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# 方法3: ss
|
|
56
|
+
if command -v ss &>/dev/null; then
|
|
57
|
+
pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
|
|
58
|
+
if [ -n "$pid" ]; then
|
|
59
|
+
echo "$pid"
|
|
60
|
+
return
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# 方法4: netstat
|
|
34
65
|
if command -v netstat &>/dev/null; then
|
|
35
|
-
|
|
36
|
-
pid=$(netstat -tnlp 2>/dev/null | grep ":18789 " | head -1 | awk '{print $7}' | cut -d'/' -f1)
|
|
66
|
+
pid=$(netstat -tnlp 2>/dev/null | grep ":${port} " | head -1 | awk '{print $7}' | cut -d'/' -f1)
|
|
37
67
|
if [ -n "$pid" ]; then
|
|
38
68
|
echo "$pid"
|
|
39
69
|
return
|
|
40
70
|
fi
|
|
41
71
|
fi
|
|
42
72
|
|
|
43
|
-
#
|
|
73
|
+
# 方法5: 通过 /proc/net/tcp 查找(不需要外部工具,最可靠)
|
|
74
|
+
# 端口 18789 的十六进制 = 0x4965
|
|
75
|
+
local hex_port="4965"
|
|
76
|
+
for proc_dir in /proc/[0-9]*; do
|
|
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
|
|
83
|
+
fi
|
|
84
|
+
done
|
|
85
|
+
|
|
44
86
|
echo ""
|
|
45
87
|
}
|
|
46
88
|
|
|
@@ -48,12 +90,21 @@ get_openclaw_pid() {
|
|
|
48
90
|
check_port() {
|
|
49
91
|
local port=$1
|
|
50
92
|
if command -v ss &>/dev/null; then
|
|
51
|
-
ss -tln | grep -q ":$port "
|
|
93
|
+
ss -tln 2>/dev/null | grep -q ":$port "
|
|
94
|
+
return $?
|
|
52
95
|
elif command -v netstat &>/dev/null; then
|
|
53
|
-
netstat -tln | grep -q ":$port "
|
|
96
|
+
netstat -tln 2>/dev/null | grep -q ":$port "
|
|
97
|
+
return $?
|
|
98
|
+
elif command -v lsof &>/dev/null; then
|
|
99
|
+
lsof -i :$port 2>/dev/null | grep -q LISTEN
|
|
100
|
+
return $?
|
|
101
|
+
elif command -v fuser &>/dev/null; then
|
|
102
|
+
fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
|
|
103
|
+
return $?
|
|
54
104
|
else
|
|
55
105
|
# 降级:直接检查进程
|
|
56
106
|
[ -n "$(get_openclaw_pid)" ]
|
|
107
|
+
return $?
|
|
57
108
|
fi
|
|
58
109
|
}
|
|
59
110
|
|
|
@@ -96,25 +147,41 @@ restart_docker() {
|
|
|
96
147
|
fi
|
|
97
148
|
|
|
98
149
|
# 如果正在运行,先停止
|
|
99
|
-
if [ -n "$pid" ]; then
|
|
150
|
+
if [ -n "$pid" ] || check_port "$PORT"; then
|
|
100
151
|
log_info "正在停止 OpenClaw 服务..."
|
|
101
|
-
|
|
152
|
+
if [ -n "$pid" ]; then
|
|
153
|
+
kill "$pid" &>/dev/null || true
|
|
154
|
+
fi
|
|
102
155
|
|
|
103
|
-
# 等待停止(最多
|
|
156
|
+
# 等待停止(最多 10 秒),使用端口双重验证
|
|
104
157
|
local elapsed=0
|
|
105
|
-
while [ $elapsed -lt
|
|
106
|
-
|
|
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
|
|
107
162
|
break
|
|
108
163
|
fi
|
|
109
164
|
sleep 1
|
|
110
165
|
elapsed=$((elapsed + 1))
|
|
111
166
|
done
|
|
112
167
|
|
|
113
|
-
#
|
|
114
|
-
if
|
|
115
|
-
log_warn "服务未在
|
|
116
|
-
|
|
117
|
-
|
|
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
|
|
118
185
|
fi
|
|
119
186
|
|
|
120
187
|
log_info "服务已停止"
|
package/command/linux/start.sh
CHANGED
|
@@ -30,17 +30,59 @@ is_docker() {
|
|
|
30
30
|
|
|
31
31
|
# 获取 openclaw 进程 PID
|
|
32
32
|
get_openclaw_pid() {
|
|
33
|
-
|
|
33
|
+
local port=18789
|
|
34
|
+
local pid=""
|
|
35
|
+
|
|
36
|
+
# 按优先级尝试多种工具(适配精简 Docker 镜像)
|
|
37
|
+
# 方法1: lsof(最可靠)
|
|
38
|
+
if command -v lsof &>/dev/null; then
|
|
39
|
+
pid=$(lsof -i :${port} -t 2>/dev/null | head -1)
|
|
40
|
+
if [ -n "$pid" ]; then
|
|
41
|
+
echo "$pid"
|
|
42
|
+
return
|
|
43
|
+
fi
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# 方法2: fuser
|
|
47
|
+
if command -v fuser &>/dev/null; then
|
|
48
|
+
pid=$(fuser ${port}/tcp 2>/dev/null | tr -d ' ')
|
|
49
|
+
if [ -n "$pid" ]; then
|
|
50
|
+
echo "$pid"
|
|
51
|
+
return
|
|
52
|
+
fi
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# 方法3: ss
|
|
56
|
+
if command -v ss &>/dev/null; then
|
|
57
|
+
pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
|
|
58
|
+
if [ -n "$pid" ]; then
|
|
59
|
+
echo "$pid"
|
|
60
|
+
return
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# 方法4: netstat
|
|
34
65
|
if command -v netstat &>/dev/null; then
|
|
35
|
-
|
|
36
|
-
pid=$(netstat -tnlp 2>/dev/null | grep ":18789 " | head -1 | awk '{print $7}' | cut -d'/' -f1)
|
|
66
|
+
pid=$(netstat -tnlp 2>/dev/null | grep ":${port} " | head -1 | awk '{print $7}' | cut -d'/' -f1)
|
|
37
67
|
if [ -n "$pid" ]; then
|
|
38
68
|
echo "$pid"
|
|
39
69
|
return
|
|
40
70
|
fi
|
|
41
71
|
fi
|
|
42
72
|
|
|
43
|
-
#
|
|
73
|
+
# 方法5: 通过 /proc/net/tcp 查找(不需要外部工具,最可靠)
|
|
74
|
+
# 端口 18789 的十六进制 = 0x4965
|
|
75
|
+
local hex_port="4965"
|
|
76
|
+
for proc_dir in /proc/[0-9]*; do
|
|
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
|
|
83
|
+
fi
|
|
84
|
+
done
|
|
85
|
+
|
|
44
86
|
echo ""
|
|
45
87
|
}
|
|
46
88
|
|
|
@@ -48,12 +90,21 @@ get_openclaw_pid() {
|
|
|
48
90
|
check_port() {
|
|
49
91
|
local port=$1
|
|
50
92
|
if command -v ss &>/dev/null; then
|
|
51
|
-
ss -tln | grep -q ":$port "
|
|
93
|
+
ss -tln 2>/dev/null | grep -q ":$port "
|
|
94
|
+
return $?
|
|
52
95
|
elif command -v netstat &>/dev/null; then
|
|
53
|
-
netstat -tln | grep -q ":$port "
|
|
96
|
+
netstat -tln 2>/dev/null | grep -q ":$port "
|
|
97
|
+
return $?
|
|
98
|
+
elif command -v lsof &>/dev/null; then
|
|
99
|
+
lsof -i :$port 2>/dev/null | grep -q LISTEN
|
|
100
|
+
return $?
|
|
101
|
+
elif command -v fuser &>/dev/null; then
|
|
102
|
+
fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
|
|
103
|
+
return $?
|
|
54
104
|
else
|
|
55
105
|
# 降级:直接检查进程
|
|
56
106
|
[ -n "$(get_openclaw_pid)" ]
|
|
107
|
+
return $?
|
|
57
108
|
fi
|
|
58
109
|
}
|
|
59
110
|
|
package/command/linux/status.sh
CHANGED
|
@@ -44,17 +44,59 @@ is_docker() {
|
|
|
44
44
|
|
|
45
45
|
# 获取 openclaw 进程 PID
|
|
46
46
|
get_openclaw_pid() {
|
|
47
|
-
|
|
47
|
+
local port=18789
|
|
48
|
+
local pid=""
|
|
49
|
+
|
|
50
|
+
# 按优先级尝试多种工具(适配精简 Docker 镜像)
|
|
51
|
+
# 方法1: lsof(最可靠)
|
|
52
|
+
if command -v lsof &>/dev/null; then
|
|
53
|
+
pid=$(lsof -i :${port} -t 2>/dev/null | head -1)
|
|
54
|
+
if [ -n "$pid" ]; then
|
|
55
|
+
echo "$pid"
|
|
56
|
+
return
|
|
57
|
+
fi
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# 方法2: fuser
|
|
61
|
+
if command -v fuser &>/dev/null; then
|
|
62
|
+
pid=$(fuser ${port}/tcp 2>/dev/null | tr -d ' ')
|
|
63
|
+
if [ -n "$pid" ]; then
|
|
64
|
+
echo "$pid"
|
|
65
|
+
return
|
|
66
|
+
fi
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
# 方法3: ss
|
|
70
|
+
if command -v ss &>/dev/null; then
|
|
71
|
+
pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
|
|
72
|
+
if [ -n "$pid" ]; then
|
|
73
|
+
echo "$pid"
|
|
74
|
+
return
|
|
75
|
+
fi
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# 方法4: netstat
|
|
48
79
|
if command -v netstat &>/dev/null; then
|
|
49
|
-
|
|
50
|
-
pid=$(netstat -tnlp 2>/dev/null | grep ":18789 " | head -1 | awk '{print $7}' | cut -d'/' -f1)
|
|
80
|
+
pid=$(netstat -tnlp 2>/dev/null | grep ":${port} " | head -1 | awk '{print $7}' | cut -d'/' -f1)
|
|
51
81
|
if [ -n "$pid" ]; then
|
|
52
82
|
echo "$pid"
|
|
53
83
|
return
|
|
54
84
|
fi
|
|
55
85
|
fi
|
|
56
86
|
|
|
57
|
-
#
|
|
87
|
+
# 方法5: 通过 /proc/net/tcp 查找(不需要外部工具,最可靠)
|
|
88
|
+
# 端口 18789 的十六进制 = 0x4965
|
|
89
|
+
local hex_port="4965"
|
|
90
|
+
for proc_dir in /proc/[0-9]*; do
|
|
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
|
|
97
|
+
fi
|
|
98
|
+
done
|
|
99
|
+
|
|
58
100
|
echo ""
|
|
59
101
|
}
|
|
60
102
|
|
|
@@ -62,12 +104,21 @@ get_openclaw_pid() {
|
|
|
62
104
|
check_port() {
|
|
63
105
|
local port=$1
|
|
64
106
|
if command -v ss &>/dev/null; then
|
|
65
|
-
ss -tln | grep -q ":$port "
|
|
107
|
+
ss -tln 2>/dev/null | grep -q ":$port "
|
|
108
|
+
return $?
|
|
66
109
|
elif command -v netstat &>/dev/null; then
|
|
67
|
-
netstat -tln | grep -q ":$port "
|
|
110
|
+
netstat -tln 2>/dev/null | grep -q ":$port "
|
|
111
|
+
return $?
|
|
112
|
+
elif command -v lsof &>/dev/null; then
|
|
113
|
+
lsof -i :$port 2>/dev/null | grep -q LISTEN
|
|
114
|
+
return $?
|
|
115
|
+
elif command -v fuser &>/dev/null; then
|
|
116
|
+
fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
|
|
117
|
+
return $?
|
|
68
118
|
else
|
|
69
119
|
# 降级:直接检查进程
|
|
70
120
|
[ -n "$(get_openclaw_pid)" ]
|
|
121
|
+
return $?
|
|
71
122
|
fi
|
|
72
123
|
}
|
|
73
124
|
|
package/command/linux/stop.sh
CHANGED
|
@@ -42,27 +42,80 @@ PORT="18789"
|
|
|
42
42
|
# 检查端口是否监听
|
|
43
43
|
check_port() {
|
|
44
44
|
local port=$1
|
|
45
|
-
if command -v
|
|
46
|
-
|
|
45
|
+
if command -v ss &>/dev/null; then
|
|
46
|
+
ss -tln 2>/dev/null | grep -q ":$port "
|
|
47
|
+
return $?
|
|
48
|
+
elif command -v netstat &>/dev/null; then
|
|
49
|
+
netstat -tln 2>/dev/null | grep -q ":$port "
|
|
50
|
+
return $?
|
|
51
|
+
elif command -v lsof &>/dev/null; then
|
|
52
|
+
lsof -i :$port 2>/dev/null | grep -q LISTEN
|
|
53
|
+
return $?
|
|
54
|
+
elif command -v fuser &>/dev/null; then
|
|
55
|
+
fuser $port/tcp 2>/dev/null | grep -q '[0-9]'
|
|
56
|
+
return $?
|
|
47
57
|
else
|
|
48
|
-
#
|
|
58
|
+
# 最后降级:直接检查进程
|
|
49
59
|
[ -n "$(get_openclaw_pid)" ]
|
|
60
|
+
return $?
|
|
50
61
|
fi
|
|
51
62
|
}
|
|
52
63
|
|
|
53
64
|
# 获取 openclaw 进程 PID
|
|
54
65
|
get_openclaw_pid() {
|
|
55
|
-
|
|
66
|
+
local port=18789
|
|
67
|
+
local pid=""
|
|
68
|
+
|
|
69
|
+
# 按优先级尝试多种工具(适配精简 Docker 镜像)
|
|
70
|
+
# 方法1: lsof(最可靠)
|
|
71
|
+
if command -v lsof &>/dev/null; then
|
|
72
|
+
pid=$(lsof -i :${port} -t 2>/dev/null | head -1)
|
|
73
|
+
if [ -n "$pid" ]; then
|
|
74
|
+
echo "$pid"
|
|
75
|
+
return
|
|
76
|
+
fi
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
# 方法2: fuser
|
|
80
|
+
if command -v fuser &>/dev/null; then
|
|
81
|
+
pid=$(fuser ${port}/tcp 2>/dev/null | tr -d ' ')
|
|
82
|
+
if [ -n "$pid" ]; then
|
|
83
|
+
echo "$pid"
|
|
84
|
+
return
|
|
85
|
+
fi
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# 方法3: ss
|
|
89
|
+
if command -v ss &>/dev/null; then
|
|
90
|
+
pid=$(ss -tlnp 2>/dev/null | grep ":${port} " | head -1 | sed -n 's/.*pid=\([0-9]*\).*/\1/p')
|
|
91
|
+
if [ -n "$pid" ]; then
|
|
92
|
+
echo "$pid"
|
|
93
|
+
return
|
|
94
|
+
fi
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# 方法4: netstat
|
|
56
98
|
if command -v netstat &>/dev/null; then
|
|
57
|
-
|
|
58
|
-
pid=$(netstat -tnlp 2>/dev/null | grep ":18789 " | head -1 | awk '{print $7}' | cut -d'/' -f1)
|
|
99
|
+
pid=$(netstat -tnlp 2>/dev/null | grep ":${port} " | head -1 | awk '{print $7}' | cut -d'/' -f1)
|
|
59
100
|
if [ -n "$pid" ]; then
|
|
60
101
|
echo "$pid"
|
|
61
102
|
return
|
|
62
103
|
fi
|
|
63
104
|
fi
|
|
64
105
|
|
|
65
|
-
#
|
|
106
|
+
# 方法5: 通过 /proc/net/tcp 查找(不需要外部工具,最可靠)
|
|
107
|
+
# 端口 18789 的十六进制 = 0x4965
|
|
108
|
+
local hex_port="4965"
|
|
109
|
+
for proc_dir in /proc/[0-9]*; do
|
|
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
|
|
116
|
+
fi
|
|
117
|
+
done
|
|
118
|
+
|
|
66
119
|
echo ""
|
|
67
120
|
}
|
|
68
121
|
|
|
@@ -74,6 +127,32 @@ stop_docker() {
|
|
|
74
127
|
# 检查服务状态
|
|
75
128
|
log_info "检查 OpenClaw 服务状态..."
|
|
76
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
|
|
77
156
|
log_warn "OpenClaw 服务未在运行。"
|
|
78
157
|
exit 0
|
|
79
158
|
fi
|
|
@@ -81,14 +160,17 @@ stop_docker() {
|
|
|
81
160
|
log_info "OpenClaw 服务正在运行(PID: $pid),准备停止..."
|
|
82
161
|
|
|
83
162
|
# 停止服务:先发送 SIGTERM(优雅停止)
|
|
84
|
-
log_info "正在停止 OpenClaw
|
|
163
|
+
log_info "正在停止 OpenClaw 服务(发送 SIGTERM)..."
|
|
85
164
|
kill "$pid" &>/dev/null || true
|
|
86
165
|
|
|
87
|
-
# 等待服务完全停止(最多 10
|
|
166
|
+
# 等待服务完全停止(最多 10 秒),使用端口双重验证
|
|
88
167
|
local elapsed=0
|
|
89
168
|
while [ $elapsed -lt 10 ]; do
|
|
90
|
-
|
|
91
|
-
|
|
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 和端口均已关闭)"
|
|
92
174
|
log_info "服务已成功停止。"
|
|
93
175
|
log_info "Success"
|
|
94
176
|
exit 0
|
|
@@ -101,32 +183,38 @@ stop_docker() {
|
|
|
101
183
|
log_warn "服务未在 10 秒内停止,正在强制停止..."
|
|
102
184
|
kill -9 "$pid" &>/dev/null || true
|
|
103
185
|
|
|
104
|
-
#
|
|
186
|
+
# 额外:尝试 pkill 确保所有相关进程都被停止
|
|
187
|
+
pkill -9 -f "openclaw" &>/dev/null || true
|
|
188
|
+
|
|
189
|
+
# 等待进程消失(最多 5 秒)
|
|
105
190
|
elapsed=0
|
|
106
|
-
while [ $elapsed -lt
|
|
107
|
-
|
|
108
|
-
|
|
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
|
|
109
199
|
fi
|
|
110
200
|
sleep 1
|
|
111
201
|
elapsed=$((elapsed + 1))
|
|
112
202
|
done
|
|
113
203
|
|
|
114
|
-
#
|
|
115
|
-
# 使用端口检测作为辅助,避免僵尸进程导致误判
|
|
204
|
+
# 最终验证
|
|
116
205
|
local current_pid
|
|
117
206
|
current_pid=$(get_openclaw_pid)
|
|
118
|
-
if [ -z "$current_pid" ]; then
|
|
119
|
-
log_info "OpenClaw
|
|
207
|
+
if [ -z "$current_pid" ] && ! check_port "$PORT"; then
|
|
208
|
+
log_info "OpenClaw 服务已停止。"
|
|
120
209
|
log_info "服务已成功停止。"
|
|
121
210
|
log_info "Success"
|
|
122
|
-
elif
|
|
123
|
-
|
|
211
|
+
elif check_port "$PORT"; then
|
|
212
|
+
log_error "OpenClaw 服务停止失败!端口 $PORT 仍在监听。"
|
|
213
|
+
exit 1
|
|
214
|
+
else
|
|
124
215
|
log_info "OpenClaw 服务已停止(端口已关闭)。"
|
|
125
216
|
log_info "服务已成功停止。"
|
|
126
217
|
log_info "Success"
|
|
127
|
-
else
|
|
128
|
-
log_error "OpenClaw 服务停止失败!进程仍然存在且端口仍在监听。"
|
|
129
|
-
exit 1
|
|
130
218
|
fi
|
|
131
219
|
}
|
|
132
220
|
|
package/package.json
CHANGED
|
@@ -25,6 +25,7 @@ class RongyunMessageHandler {
|
|
|
25
25
|
this.config = config;
|
|
26
26
|
this.log = log;
|
|
27
27
|
this.commandLock = false;
|
|
28
|
+
this.commandLockTimer = null;
|
|
28
29
|
this.messageSender = null;
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -126,6 +127,13 @@ class RongyunMessageHandler {
|
|
|
126
127
|
}
|
|
127
128
|
|
|
128
129
|
this.commandLock = true;
|
|
130
|
+
// 设置 60 秒超时保护,防止命令永久卡住导致锁无法释放
|
|
131
|
+
this.commandLockTimer = setTimeout(() => {
|
|
132
|
+
this.logWarn('[RongyunMessageHandler] 命令锁超时(60秒),自动释放');
|
|
133
|
+
this.commandLock = false;
|
|
134
|
+
this.commandLockTimer = null;
|
|
135
|
+
}, 60000);
|
|
136
|
+
|
|
129
137
|
try {
|
|
130
138
|
await executeCommand(command, null, async (response) => {
|
|
131
139
|
// 增加短暂延迟,避免融云 SDK 在收到消息后立刻回复时消息丢失
|
|
@@ -146,6 +154,10 @@ class RongyunMessageHandler {
|
|
|
146
154
|
}, requestId, sourceId);
|
|
147
155
|
} finally {
|
|
148
156
|
this.commandLock = false;
|
|
157
|
+
if (this.commandLockTimer) {
|
|
158
|
+
clearTimeout(this.commandLockTimer);
|
|
159
|
+
this.commandLockTimer = null;
|
|
160
|
+
}
|
|
149
161
|
}
|
|
150
162
|
}
|
|
151
163
|
|
|
@@ -285,15 +285,6 @@ class ScriptExecutor {
|
|
|
285
285
|
}
|
|
286
286
|
});
|
|
287
287
|
|
|
288
|
-
// 错误处理
|
|
289
|
-
child.on('error', (err) => {
|
|
290
|
-
console.error(`[ScriptExecutor] 子进程错误: ${err.message}`);
|
|
291
|
-
if (!killed) {
|
|
292
|
-
killed = true;
|
|
293
|
-
clearTimeout(timer);
|
|
294
|
-
reject(err);
|
|
295
|
-
}
|
|
296
|
-
});
|
|
297
288
|
});
|
|
298
289
|
}
|
|
299
290
|
|
|
@@ -356,6 +347,7 @@ class ScriptExecutor {
|
|
|
356
347
|
|
|
357
348
|
if (
|
|
358
349
|
upper.includes('OPENCLAW COMMAND NOT FOUND') ||
|
|
350
|
+
upper.includes('OPENCLAW 命令未找到') ||
|
|
359
351
|
output.includes('服务 openclaw-gateway.service 未安装') ||
|
|
360
352
|
output.includes('服务 openclaw-gateway.service 不存在') ||
|
|
361
353
|
upper.includes('OPENCLAW-GATEWAY.SERVICE 不存在')
|