golang連接ssh遠程執行命令

直接上代碼:

package main

import (
	"bufio"
	_ "bytes"
	"fmt"
	"golang.org/x/crypto/ssh"
	"log"
	"os"
)

type MyReader struct {

}
var cmdChannel = make(chan string)

func (r MyReader)Read(p []byte) (n int, err error)  {
	var cmd string
	fmt.Println("into Read...")
	cmd = <-cmdChannel
	cmdB:=[]byte(cmd+"\n")
	for i,v:=range cmdB {
		p[i]=v
	}
	n=len(cmdB)
    fmt.Println("leave Read.")
	return n, err
}

type MyWriter struct {

}
var resChannel=make(chan string)
func (w MyWriter)Write(p []byte) (n int, err error)  {
	res :=string(p)
	fmt.Println("into Write...")
	fmt.Println(res)
	resChannel<-res
	fmt.Println("leave Write.")
	return len(p),err
}

func main() {
	ce := func(err error, msg string) {
		if err != nil {
			log.Fatalf("%s error: %v", msg, err)
		}
	}

	client, err := ssh.Dial("tcp", "192.168.161.130:22", &ssh.ClientConfig{
		User: "sololife",
		Auth: []ssh.AuthMethod{ssh.Password("522121803")},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	})
	ce(err, "dial")

	session, err := client.NewSession()
	ce(err, "new session")
	defer session.Close()
	//session.Stdout = os.Stdout
	//session.Stderr = os.Stderr
	//session.Stdin = os.Stdin
	session.Stdout = new(MyWriter)
	session.Stderr = new(MyWriter)
	session.Stdin = new(MyReader)

	modes := ssh.TerminalModes{
		ssh.ECHO:          0,
		ssh.TTY_OP_ISPEED: 14400,
		ssh.TTY_OP_OSPEED: 14400,
	}
	term:="xterm"
	//term = "vt100"
	err = session.RequestPty(term, 25, 80, modes)
	ce(err, "request pty")

	err = session.Shell()
	ce(err, "start shell")
	//goto end

	go func() {
		for{
			//fmt.Println("獲之前")
			res:=<-resChannel
			fmt.Println([]byte(res))
			//fmt.Println("獲之後")
		}
	}()

	go func() {
		f := bufio.NewReader(os.Stdin) //讀取輸入的內容
		for{
			var str string
			arg:=""
			Input,_ := f.ReadString('\n')             //定義一行輸入的內容分隔符。
			_, _ = fmt.Sscan(Input, &str,&arg) //將Input
			fmt.Println(string(str),"str--------------")
			if len(arg) > 0{
				arg=" "+arg
			}
			cmdChannel<- str+arg
		}
	}()
	//end:
	err = session.Wait()
	//ce(err, "return")
}

版本02:

package main

import (
	"bufio"
	_ "bytes"
	"fmt"
	"golang.org/x/crypto/ssh"
	"log"
	"os"
)

type MyReader struct {
	channel chan string
}

func newReader() *MyReader {
	reader := new(MyReader)
	reader.channel = make(chan string)
	return reader
}

func (r *MyReader) Read(p []byte) (n int, err error) {
	var cmd string
	fmt.Println("into Read...")
	cmd = <-r.channel
	cmdB := []byte(cmd + "\n")
	for i, v := range cmdB {
		p[i] = v
	}
	n = len(cmdB)
	fmt.Println("leave Read.")
	return n, err
}

type MyWriter struct {
	channel chan string
}

func newWriter() *MyWriter {
	writer := new(MyWriter)
	writer.channel = make(chan string)
	return writer
}

func (w *MyWriter) Write(p []byte) (n int, err error) {
	res := string(p)
	fmt.Println("into Write...")
	//fmt.Println(res)
	w.channel <- res
	fmt.Println("leave Write.")
	return len(p), err
}

func main() {
	ce := func(err error, msg string) {
		if err != nil {
			log.Fatalf("%s error: %v", msg, err)
		}
	}
	client, err := ssh.Dial("tcp", "192.168.161.130:22", &ssh.ClientConfig{
		User:            "sololife",
		Auth:            []ssh.AuthMethod{ssh.Password("522121803")},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	})
	ce(err, "dial")
	session, err := client.NewSession()
	ce(err, "new session")
	defer session.Close()
	writer := newWriter()
	reader := newReader()
	session.Stdout = writer
	session.Stderr = os.Stderr
	session.Stdin = reader
	modes := ssh.TerminalModes{
		ssh.ECHO:          0,
		ssh.TTY_OP_ISPEED: 14400,
		ssh.TTY_OP_OSPEED: 14400,
	}
	term := "xterm"
	//term = "vt100"
	err = session.RequestPty(term, 25, 80, modes)
	ce(err, "request pty")
	err = session.Shell()
	ce(err, "start shell")
	go func() {
		for {
			res := <-writer.channel
			fmt.Println([]byte(res))
		}
	}()
	go func() {
		f := bufio.NewReader(os.Stdin) //讀取輸入的內容
		for {
			var str string
			arg := ""
			Input, _ := f.ReadString('\n')      //定義一行輸入的內容分隔符。
			_, _ = fmt.Sscan(Input, &str, &arg) //將Input
			if len(arg) > 0 {
				arg = " " + arg
			}
			reader.channel <- str + arg
		}
	}()
	err = session.Wait()
	ce(err, "return")
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章