Golang获取HP路由器远程命令输出的方法
Golang获取HP路由器远程命令输出的方法 我的任务是在不同的路由器上执行命令。
我使用的是 golang.org/x/crypto/ssh 包。
思科路由器工作正常。但在惠普路由器上,输出在命令实际执行前就结束了。 以下是代码示例:
cmd := "dis int brief"
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
...
}
...
conn, err := ssh.Dial("tcp", hostip+":22", config)
session, err := conn.NewSession()
output, err := session.CombinedOutput(cmd)
在输出中,我只得到了实际命令之前的文本,就像它是前一个命令的缓冲区,但我也没有收到任何错误。
有人知道惠普路由器的问题是什么吗?
更多关于Golang获取HP路由器远程命令输出的方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang获取HP路由器远程命令输出的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这个问题通常与HP网络设备(如Comware系统)的SSH实现方式有关。HP设备在SSH会话中执行命令时,可能需要显式地发送终端类型并处理提示符。
以下是修改后的代码示例,添加了伪终端(PTY)配置:
package main
import (
"fmt"
"golang.org/x/crypto/ssh"
"log"
)
func executeHPCommand(hostip, user, password, cmd string) (string, error) {
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
conn, err := ssh.Dial("tcp", hostip+":22", config)
if err != nil {
return "", err
}
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
return "", err
}
defer session.Close()
// 为HP路由器设置伪终端
modes := ssh.TerminalModes{
ssh.ECHO: 0, // 禁用回显
ssh.TTY_OP_ISPEED: 14400, // 输入速度
ssh.TTY_OP_OSPEED: 14400, // 输出速度
}
// 请求PTY,指定终端类型
if err := session.RequestPty("vt100", 80, 40, modes); err != nil {
return "", err
}
// 执行命令并获取输出
output, err := session.CombinedOutput(cmd)
if err != nil {
return "", err
}
return string(output), nil
}
func main() {
output, err := executeHPCommand("192.168.1.1", "admin", "password", "dis int brief")
if err != nil {
log.Fatal(err)
}
fmt.Println(output)
}
如果问题仍然存在,可以尝试使用交互式会话的方式:
func executeHPCommandInteractive(hostip, user, password, cmd string) (string, error) {
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{
ssh.Password(password),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
conn, err := ssh.Dial("tcp", hostip+":22", config)
if err != nil {
return "", err
}
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
return "", err
}
defer session.Close()
// 获取输入输出管道
stdin, err := session.StdinPipe()
if err != nil {
return "", err
}
stdout, err := session.StdoutPipe()
if err != nil {
return "", err
}
// 设置伪终端
modes := ssh.TerminalModes{
ssh.ECHO: 0,
ssh.TTY_OP_ISPEED: 14400,
ssh.TTY_OP_OSPEED: 14400,
}
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
return "", err
}
// 启动shell
if err := session.Shell(); err != nil {
return "", err
}
// 发送命令
_, err = fmt.Fprintf(stdin, "%s\n", cmd)
if err != nil {
return "", err
}
// 读取输出
buf := make([]byte, 4096)
n, err := stdout.Read(buf)
if err != nil {
return "", err
}
// 发送退出命令
fmt.Fprintf(stdin, "quit\n")
return string(buf[:n]), nil
}
对于HP路由器,还可以尝试在命令后添加换行符和等待时间:
// 在原有代码基础上修改命令执行部分
cmd := "dis int brief\n"
output, err := session.CombinedOutput(cmd)
// 或者使用带超时的执行
import "time"
func executeWithTimeout(session *ssh.Session, cmd string, timeout time.Duration) (string, error) {
done := make(chan error, 1)
var output []byte
var err error
go func() {
output, err = session.CombinedOutput(cmd)
done <- err
}()
select {
case <-time.After(timeout):
return "", fmt.Errorf("command timed out")
case err := <-done:
if err != nil {
return "", err
}
return string(output), nil
}
}
这些修改应该能解决HP路由器上命令输出不完整的问题。关键点在于正确配置PTY和终端类型,以及处理设备特定的SSH实现差异。

