Fix: 使用分隔符标记提取单个命令输出

- 在Shell模式中插入分隔符标记命令边界
- 解决累积输出包含之前命令回显的问题
- display interface等待8秒,lldp等待3秒
This commit is contained in:
Your Name
2026-04-26 03:23:28 +08:00
parent 87d233659c
commit 4d3b737e2d
+34 -10
View File
@@ -182,34 +182,58 @@ func (c *Client) ExecuteCommands(commands []string) ([]string, error) {
return nil, fmt.Errorf("failed to start shell: %w", err)
}
// 执行命令并收集输出
// 执行命令并收集输出(使用分隔符标记)
results := make([]string, 0, len(commands))
for i, cmd := range commands {
// 等待一段时间防止设备速率限制
if i > 0 {
time.Sleep(2 * time.Second)
}
// 发送命令(添加换行符)
// 生成分隔符标记命令边界
delimiter := fmt.Sprintf("===CMD_BOUNDARY_%d===", i)
// 发送命令
if _, err := stdin.Write([]byte(cmd + "\n")); err != nil {
return results, fmt.Errorf("failed to send command '%s': %w", cmd, err)
}
// 等待命令执行完成(不同命令需要不同等待时间)
sleepTime := 1 * time.Second
if cmd == "display interface" {
sleepTime = 5 * time.Second // 大输出命令需要更多时间
if cmd == "display interface" || strings.Contains(cmd, "display interface") {
sleepTime = 8 * time.Second // 大输出命令需要更多时间
} else if cmd == "display lldp neighbor-information" {
sleepTime = 3 * time.Second
}
time.Sleep(sleepTime)
// 发送分隔符(不执行任何操作,只是标记)
if _, err := stdin.Write([]byte("echo " + delimiter + "\n")); err != nil {
return results, fmt.Errorf("failed to send delimiter: %w", err)
}
// 等待分隔符输出
time.Sleep(500 * time.Millisecond)
// 获取当前输出并清理
// 获取完整输出并清理
rawOutput := stdoutBuf.String()
cleanOutput := cleanCommandOutput(rawOutput, cmd)
// 找到分隔符位置,提取当前命令的输出部分
parts := strings.Split(rawOutput, delimiter)
cmdOutput := ""
if len(parts) > 1 {
// 取最后一个分隔符之前的部分(当前命令的输出)
cmdOutput = parts[len(parts)-2] // 倒数第二部分是当前命令输出,最后一部分是分隔符后的空内容
} else {
cmdOutput = rawOutput
}
cleanOutput := cleanCommandOutput(cmdOutput, cmd)
results = append(results, cleanOutput)
// 清空缓冲区,为下一个命令做准备(通过位置标记)
stdoutBuf.Reset()
stderrBuf.Reset()
fmt.Printf("[SSH] Command '%s' extracted %d bytes from %d bytes raw output\n",
cmd, len(cleanOutput), len(rawOutput))
}
// 退出shell