(msg: Api.Message)
| 222 | const validated = sanitizeServiceName(args[0]); |
| 223 | if (!validated) { |
| 224 | await msg.edit({ text: `❌ 服务名称包含非法字符,只允许字母、数字、-、_、.和@` }); |
| 225 | return; |
| 226 | } |
| 227 | serviceName = validated; |
| 228 | } else { |
| 229 | // 自动检测当前服务名称 |
| 230 | await msg.edit({ text: "🔍 正在自动检测当前服务..." }); |
| 231 | serviceName = await getCurrentServiceName(); |
| 232 | isAutoDetected = true; |
| 233 | } |
| 234 | |
| 235 | // 显示正在查询的提示 |
| 236 | await msg.edit({ text: `🔍 正在检查 ${htmlEscape(serviceName)} 服务状态...` }); |
| 237 | |
| 238 | try { |
| 239 | // 获取完整的systemd状态信息,包括内存限制和告警阈值 |
| 240 | // Use execFile to avoid shell injection — serviceName is now validated, |
| 241 | // and we pass args as an array instead of string interpolation. |
| 242 | const { stdout: rawStatus } = await execFileAsync("systemctl", [ |
| 243 | "--no-pager", "status", serviceName, |
| 244 | ]); |
| 245 | |
| 246 | // Filter lines locally instead of piping through shell |
| 247 | const stdout = rawStatus |
| 248 | .split("\n") |
| 249 | .filter(line => /Active|PID|Tasks|Memory|CPU|limit|high|max|available/i.test(line) && !line.includes("grep")) |
| 250 | .join("\n"); |
| 251 | |
| 252 | if (stdout.includes("not be found") || stdout.includes("could not be found")) { |
| 253 | await msg.edit({ text: `❌ 服务 '${serviceName}' 未找到。` }); |
| 254 | return; |
| 255 | } |
| 256 | |
| 257 | if (stdout.includes("inactive")) { |
| 258 | await msg.edit({ text: `🔴 服务 '${serviceName}' 已停止 (未运行)。` }); |
| 259 | return; |
| 260 | } |
| 261 | |
| 262 | const lines = stdout.split("\n"); |
| 263 | const uptime = getBotUptime(); |
| 264 | |
| 265 | for (let i = 0; i < lines.length; i++) { |
| 266 | let line = lines[i].trim(); |
| 267 | |
| 268 | if (line.includes("Active:")) { |
| 269 | line = line.replace("Active:", "").replace("ago", "").trim(); |
| 270 | const [beforeSince, afterSince] = line.split("since"); |
| 271 | |
| 272 | if (afterSince) { |
| 273 | const [sinceTime, uptimeInfo] = afterSince.split(";"); |
| 274 | lines[i] = `${beforeSince.trim()}\n启动时间: ${sinceTime.trim()}\n运行时间: ${uptimeInfo.trim()}`; |
| 275 | |
| 276 | // 如果是当前检测到的pagermaid服务,添加bot uptime |
| 277 | if (isAutoDetected) { |
| 278 | lines[i] += ` (${uptime})`; |
| 279 | } |
| 280 | } |
| 281 | } else { |
nothing calls this directly
no test coverage detected