From eb574b852a51bba9fdc86df4ba8186d06836870f Mon Sep 17 00:00:00 2001 From: xxjwxc Date: Tue, 26 May 2020 02:04:46 +0800 Subject: [PATCH] new --- go.sum | 1 + mylog/mylog.go | 6 ++++ mysignal/mysignal.go | 32 ++++++++++++++++++++ myssh/myssh.go | 58 +++++++++++++++++++++++++++---------- myssh/myssh_test.go | 4 +-- myssh/reader.go | 69 ++++++++++++++++++++++++++++++++++++++++++++ myssh/write.go | 42 +++++++++++++++++++++++++++ 7 files changed, 194 insertions(+), 18 deletions(-) create mode 100644 mysignal/mysignal.go create mode 100644 myssh/reader.go create mode 100644 myssh/write.go diff --git a/go.sum b/go.sum index f3f9c21..bfd570a 100644 --- a/go.sum +++ b/go.sum @@ -186,6 +186,7 @@ golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM= golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/mylog/mylog.go b/mylog/mylog.go index ae81f92..1569c81 100644 --- a/mylog/mylog.go +++ b/mylog/mylog.go @@ -74,6 +74,12 @@ func ErrorString(v ...interface{}) { log.Output(2, color.Error.Render(fmt.Sprint(v...))) } +//Fatalf 系统级错误 +func Fatalf(src string, v ...interface{}) { + log.Output(2, color.Error.Render(fmt.Sprintf(src, v...))) + os.Exit(1) +} + //Fatal 系统级错误 func Fatal(v ...interface{}) { log.Output(2, color.Error.Render(fmt.Sprint(v...))) diff --git a/mysignal/mysignal.go b/mysignal/mysignal.go new file mode 100644 index 0000000..d2e6a45 --- /dev/null +++ b/mysignal/mysignal.go @@ -0,0 +1,32 @@ +package mysignal + +import ( + "os" + "os/signal" + "syscall" +) + +type notify struct { + cc chan os.Signal +} + +// New new signal +func New() *notify { + return ¬ify{ + cc: make(chan os.Signal, 1), + } +} + +func (s *notify) Wait() { + signal.Notify(s.cc, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT) + + select { + // wait on kill signal + case <-s.cc: + } +} + +// NotifyStop 发送停止信号 +func (s *notify) NotifyStop() { + s.cc <- syscall.SIGINT +} diff --git a/myssh/myssh.go b/myssh/myssh.go index ebea373..c201159 100644 --- a/myssh/myssh.go +++ b/myssh/myssh.go @@ -2,6 +2,7 @@ package myssh import ( "fmt" + "io" "net" "os" "time" @@ -38,36 +39,46 @@ func New(ip string, username string, password string, port ...int) (*Cli, error) return cli, cli.connect() } -// Run 执行 shell脚本命令 -func (c Cli) Run(shell string) (string, error) { +// NewSession new session +func (c Cli) newSession() (*ssh.Session, error) { if c.client == nil { if err := c.connect(); err != nil { - return "", err + return nil, err } } session, err := c.client.NewSession() + if err != nil { + return nil, err + } + + return session, nil +} + +// Run 执行 shell脚本命令 +func (c Cli) Run(shell string) (string, error) { + session, err := c.newSession() if err != nil { return "", err } defer session.Close() - buf, err := session.CombinedOutput(shell) + buf, err := session.CombinedOutput(shell) return string(buf), err } // RunTerminal 执行带交互的命令 func (c *Cli) RunTerminal(shell string) error { - if c.client == nil { - if err := c.connect(); err != nil { - return err - } - } - session, err := c.client.NewSession() + session, err := c.newSession() if err != nil { return err } defer session.Close() + return c.runTerminalSession(session, shell) +} + +// runTerminalSession 执行带交互的命令 +func (c *Cli) runTerminalSession(session *ssh.Session, shell string) error { fd := int(os.Stdin.Fd()) oldState, err := terminal.MakeRaw(fd) if err != nil { @@ -99,15 +110,30 @@ func (c *Cli) RunTerminal(shell string) error { return nil } -// Terminal 进入终端 -func (c Cli) Terminal() error { - session, err := c.client.NewSession() +// EnterTerminal 完全进入终端 +func (c Cli) EnterTerminal() error { + session, err := c.newSession() if err != nil { return err } - defer session.Close() + return c.enterTerminalSession(session, os.Stdout, os.Stdin) +} + +// Enter 完全进入终端 +func (c Cli) Enter(w io.Writer, r io.Reader) error { + session, err := c.newSession() + if err != nil { + return err + } + defer session.Close() + + return c.enterTerminalSession(session, w, r) +} + +// EnterTerminalSession 进入终端 +func (c Cli) enterTerminalSession(session *ssh.Session, w io.Writer, r io.Reader) error { fd := int(os.Stdin.Fd()) oldState, err := terminal.MakeRaw(fd) if err != nil { @@ -115,9 +141,9 @@ func (c Cli) Terminal() error { } defer terminal.Restore(fd, oldState) - session.Stdout = os.Stdout + session.Stdout = w session.Stderr = os.Stdin - session.Stdin = os.Stdin + session.Stdin = r termWidth, termHeight, err := terminal.GetSize(fd) if err != nil { diff --git a/myssh/myssh_test.go b/myssh/myssh_test.go index bb9c2d1..adf2ad2 100644 --- a/myssh/myssh_test.go +++ b/myssh/myssh_test.go @@ -7,12 +7,12 @@ import ( ) func TestMain(t *testing.T) { - c, err := New("127.0.0.1", "ubuntu", "123456", 22) + c, err := New("175.24.103.30", "ubuntu", "qwer@1234", 22) if err != nil { fmt.Println("err", err) } - output, err := c.Run("free -h") + output, err := c.Run("ls") fmt.Printf("%v\n%v", output, err) // 返回字符串 time.Sleep(1 * time.Second) diff --git a/myssh/reader.go b/myssh/reader.go new file mode 100644 index 0000000..c38f929 --- /dev/null +++ b/myssh/reader.go @@ -0,0 +1,69 @@ +package myssh + +import ( + "bufio" + "fmt" + "os" + "sync/atomic" +) + +// MyReader io reader +type MyReader struct { + channel chan string + isClose int32 +} + +// NewReader new io reader +func NewReader() *MyReader { + r := &MyReader{ + channel: make(chan string), + isClose: 0, + } + return r +} + +func (r *MyReader) Read(p []byte) (n int, err error) { + fmt.Println("into Read...") + fmt.Println("=======:", string(p)) + cmd := <-r.channel + tmp := []byte(cmd + "\n") + for i, v := range tmp { + p[i] = v + } + fmt.Println("leave Read.") + return len(tmp), err +} + +// Push push one string +func (r *MyReader) Push(src string) { + r.channel <- src +} + +// ListenStdin 监听cmd 输入 +func (r *MyReader) ListenStdin() { + go func() { + f := bufio.NewReader(os.Stdin) //读取输入的内容 + for { + var str, arg string + Input, _ := f.ReadString('\n') //定义一行输入的内容分隔符。 + fmt.Sscan(Input, &str, &arg) //将Input + if len(arg) > 0 { + arg = " " + arg + } + + fmt.Println("yes:::::", str+arg) + if atomic.LoadInt32(&r.isClose) == 1 { + fmt.Println("outtttttt") + break + } else { + r.channel <- str + arg + } + } + }() +} + +// Close 关闭 +func (r *MyReader) Close() { + atomic.StoreInt32(&r.isClose, 1) + close(r.channel) +} diff --git a/myssh/write.go b/myssh/write.go new file mode 100644 index 0000000..0037a2b --- /dev/null +++ b/myssh/write.go @@ -0,0 +1,42 @@ +package myssh + +import ( + "fmt" +) + +// MyWriter io.Writer +type MyWriter struct { + channel chan string +} + +// NewWriter new writer +func NewWriter() *MyWriter { + w := &MyWriter{ + channel: make(chan string), + } + return w +} + +func (w *MyWriter) Write(p []byte) (n int, err error) { + w.channel <- string(p) + return len(p), err +} + +// Consume 消费 +func (w *MyWriter) Consume() string { + return <-w.channel +} + +// Close 关闭 +func (w *MyWriter) Close() { + close(w.channel) +} + +// Run 消费 +func (w *MyWriter) Run() { + go func() { + for res := range w.channel { + fmt.Print(res) + } + }() +}