Fix: 使用分隔符标记提取单个命令输出
- 在Shell模式中插入分隔符标记命令边界 - 解决累积输出包含之前命令回显的问题 - display interface等待8秒,lldp等待3秒
This commit is contained in:
+33
-9
@@ -182,34 +182,58 @@ func (c *Client) ExecuteCommands(commands []string) ([]string, error) {
|
|||||||
return nil, fmt.Errorf("failed to start shell: %w", err)
|
return nil, fmt.Errorf("failed to start shell: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行命令并收集输出
|
// 执行命令并收集输出(使用分隔符标记)
|
||||||
results := make([]string, 0, len(commands))
|
results := make([]string, 0, len(commands))
|
||||||
|
|
||||||
for i, cmd := range commands {
|
for i, cmd := range commands {
|
||||||
// 等待一段时间防止设备速率限制
|
// 等待一段时间防止设备速率限制
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送命令(添加换行符)
|
// 生成分隔符标记命令边界
|
||||||
|
delimiter := fmt.Sprintf("===CMD_BOUNDARY_%d===", i)
|
||||||
|
|
||||||
|
// 发送命令
|
||||||
if _, err := stdin.Write([]byte(cmd + "\n")); err != nil {
|
if _, err := stdin.Write([]byte(cmd + "\n")); err != nil {
|
||||||
return results, fmt.Errorf("failed to send command '%s': %w", cmd, err)
|
return results, fmt.Errorf("failed to send command '%s': %w", cmd, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待命令执行完成(不同命令需要不同等待时间)
|
// 等待命令执行完成(不同命令需要不同等待时间)
|
||||||
sleepTime := 1 * time.Second
|
sleepTime := 1 * time.Second
|
||||||
if cmd == "display interface" {
|
if cmd == "display interface" || strings.Contains(cmd, "display interface") {
|
||||||
sleepTime = 5 * time.Second // 大输出命令需要更多时间
|
sleepTime = 8 * time.Second // 大输出命令需要更多时间
|
||||||
|
} else if cmd == "display lldp neighbor-information" {
|
||||||
|
sleepTime = 3 * time.Second
|
||||||
}
|
}
|
||||||
time.Sleep(sleepTime)
|
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()
|
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)
|
results = append(results, cleanOutput)
|
||||||
|
|
||||||
// 清空缓冲区,为下一个命令做准备(通过位置标记)
|
fmt.Printf("[SSH] Command '%s' extracted %d bytes from %d bytes raw output\n",
|
||||||
stdoutBuf.Reset()
|
cmd, len(cleanOutput), len(rawOutput))
|
||||||
stderrBuf.Reset()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 退出shell
|
// 退出shell
|
||||||
|
|||||||
Reference in New Issue
Block a user