使用Golang SSH库时如何捕获命令输出(思科交换机场景)
捕获SSH会话Stdout输出并保存到变量(Go语言)
要将远程命令的输出保存到变量而非直接打印到控制台,你可以用bytes.Buffer替代os.Stdout来捕获会话输出,具体修改如下:
核心修改点
- 导入
bytes包,创建缓冲区对象 - 将
session.Stdout指向该缓冲区,而非os.Stdout - 会话结束后,通过缓冲区的
String()方法获取输出内容
修改后的完整代码
import ( "bytes" "fmt" "log" "time" "golang.org/x/crypto/ssh" ) func Return_current_user(conn *ssh.Client) (string, error) { session, err := conn.NewSession() if err != nil { return "", fmt.Errorf("failed to create session: %v", err) } defer session.Close() // 创建缓冲区用于捕获stdout var stdoutBuf bytes.Buffer session.Stdout = &stdoutBuf stdin, err := session.StdinPipe() if err != nil { return "", fmt.Errorf("failed to get stdin pipe: %v", err) } if err := session.Shell(); err != nil { return "", fmt.Errorf("failed to start shell: %v", err) } cmds := []string{ "show users", // 若无需进入配置模式,可去掉原代码中的"conf t",避免额外输出干扰 "exit", // 主动退出shell会话 } for _, cmd := range cmds { fmt.Fprintf(stdin, "%s\n", cmd) // 给设备留处理时间,交互式shell需等待命令执行完成 time.Sleep(1 * time.Second) } if err := session.Wait(); err != nil { return "", fmt.Errorf("session wait failed: %v", err) } // 从缓冲区获取完整输出字符串 output := stdoutBuf.String() return output, nil }
额外说明
- 重复输出问题:你之前看到两次
show users结果,是因为进入conf t配置模式后,设备的交互式shell可能保留了上下文回显。去掉不必要的conf t命令(若业务场景不需要)即可避免这类重复。 - 交互式shell同步:思科设备的shell是交互式的,直接发送命令可能因设备处理速度慢导致输出不完整,添加
time.Sleep()是基础的等待方式;若需要更可靠的控制,可使用github.com/google/goexpect这类Expect库匹配设备提示符,精准触发命令发送。 - 错误处理优化:修改后的代码将错误返回给调用方,而非直接
log.Fatal,更符合项目开发的容错需求。
内容的提问来源于stack exchange,提问作者hoa.le
相关产品推荐
相关产品推荐

