一只萌萌小番薯
这可以正常工作:package mainimport ( "bufio" "errors" "fmt" "log" "time" "golang.org/x/crypto/ssh")func main() { // List of the commands should be sent to the devices listCMDs := []string{ "set cli op-command-xml-output on\n", "test routing fib-lookup virtual-router default ip 1.1.1.1\n", "test routing fib-lookup virtual-router default ip 2.2.2.2\n", "show interface ethernet1/1\n", "show interface ethernet1/2\n", "test security-policy-match protocol 6 source 1.1.1.1 destination 2.2.2.2 destination-port 443 from ZONE1 to ZONE2\n", "test security-policy-match protocol 6 source 10.0.0.1 destination 10.0.2.1 destination-port 443 from ZONE1 to ZONE2\n", "exit", } sshconfig := InsecureClientConfig("admin", "Ghazanfar1!") s, _ := ExecCommands("192.168.1.249", listCMDs, sshconfig) for _, item := range s { fmt.Println(item) fmt.Println("-------------------------------") }}// ExecCommands ...func ExecCommands(ipAddr string, commands []string, sshconfig *ssh.ClientConfig) ([]string, error) { // Gets IP, credentials and config/commands, SSH Config (Timeout, Ciphers, ...) and returns // output of the device as "string" and an error. If error == nil, means program was able to SSH with no issue // Creating outerr as Output Error. outerr := errors.New("nil") outerr = nil // Creating Output as String var outputStr []string var strTmp string // Dial to the remote-host client, err := ssh.Dial("tcp", ipAddr+":22", sshconfig) if err != nil { log.Fatal(err) } defer client.Close() // Create sesssion session, err := client.NewSession() if err != nil { log.Fatal(err) } defer session.Close() // StdinPipee() returns a pipe that will be connected to the remote command's standard input when the command starts. // StdoutPipe() returns a pipe that will be connected to the remote command's standard output when the command starts. stdin, err := session.StdinPipe() if err != nil { log.Fatal(err) } stdout, err := session.StdoutPipe() if err != nil { log.Fatal(err) } // Start remote shell err = session.Shell() if err != nil { log.Fatal(err) } stdinLines := make(chan string) go func() { scanner := bufio.NewScanner(stdout) for scanner.Scan() { stdinLines <- scanner.Text() } if err := scanner.Err(); err != nil { log.Printf("scanner failed: %v", err) } close(stdinLines) }() // Send the commands to the remotehost one by one. for i, cmd := range commands { _, err := stdin.Write([]byte(cmd + "\n")) if err != nil { log.Fatal(err) } if i == len(commands)-1 { _ = stdin.Close() // send eof } // wait for command to complete // we'll assume the moment we've gone 1 secs w/o any output that our command is done timer := time.NewTimer(0) InputLoop: for { timer.Reset(time.Second) select { case line, ok := <-stdinLines: if !ok { log.Println("Finished processing") break InputLoop } strTmp += line strTmp += "\n" case <-timer.C: break InputLoop } } outputStr = append(outputStr, strTmp) //log.Printf("Finished processing %v\n", cmd) strTmp = "" } // Wait for session to finish err = session.Wait() if err != nil { log.Fatal(err) } return outputStr, outerr}// InsecureClientConfig ...func InsecureClientConfig(userStr, passStr string) *ssh.ClientConfig { SSHconfig := &ssh.ClientConfig{ User: userStr, Timeout: 5 * time.Second, Auth: []ssh.AuthMethod{ssh.Password(passStr)}, HostKeyCallback: ssh.InsecureIgnoreHostKey(), Config: ssh.Config{ Ciphers: []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-cbc", "aes192-cbc", "aes256-cbc", "3des-cbc", "des-cbc"}, KeyExchanges: []string{"diffie-hellman-group1-sha1", "diffie-hellman-group-exchange-sha1", "diffie-hellman-group14-sha1"}, }, } return SSHconfig}
宝慕林4294392
由于您在特殊硬件上运行的命令数量有限,并且您知道每个命令的输出模式,因此您可以使用strings.Split或regexp拆分输出。如果您没有命令,但知道任何具有独特输出模式的快速响应命令,那么您可以在以下示例中将其echo替换为命令(编号 2)。echo由于会话只接受对、、、或的一次调用,并且您不想为每个命令启动一个新会话:RunStartShellOutputCombinedOutput关键是在发送命令之前使用 astrings.Builder并将其清空,并使用将会话的标准输出同时复制 到(假设您不需要会话的标准错误):sb.Reset()io.Copystrings.Buildersb := new(strings.Builder)go io.Copy(sb, stdout)如果您知道每个命令要等待多少时间(已测试),则此方法有效:sb := new(strings.Builder)go io.Copy(sb, stdout)commands := []string{"uname -a", "sleep 1", "pwd", "whoami", "exit"}wait := []time.Duration{10, 1200, 20, 10, 10} // * time.Millisecondans := []string{}time.Sleep(10 * time.Millisecond) // wait for the ssh greetings// Send the commands to the remotehost one by one.for i, cmd := range commands { sb.Reset() fmt.Println("*** command:\t", cmd) _, err := stdin.Write([]byte(cmd + "\n")) if err != nil { log.Fatal(err) } time.Sleep(wait[i] * time.Millisecond) // wait for the command to finish s := sb.String() fmt.Println("*** response:\t", s) ans = append(ans, s)}使用字符串分隔符和strings.Split(注意:您可以echo用任何已知输出模式的快速命令替换):sb := new(strings.Builder)go io.Copy(sb, stdout)commands := []string{"uname -a", "sleep 1", "pwd", "whoami"}delim := "********--------========12345678"for _, cmd := range commands { _, err = stdin.Write([]byte("echo " + delim + "\n")) if err != nil { log.Fatal(err) } _, err := stdin.Write([]byte(cmd + "\n")) if err != nil { log.Fatal(err) }}_, err = stdin.Write([]byte("exit\n"))if err != nil { log.Fatal(err)}err = session.Wait() // Wait for session to exitif err != nil { log.Fatal(err)}ans := strings.Split(sb.String(), delim)ans = ans[1:] // remove ssh greetings