This commit is contained in:
xxjwxc
2020-05-26 02:04:46 +08:00
parent 0ac9cdd0af
commit eb574b852a
7 changed files with 194 additions and 18 deletions

1
go.sum
View File

@@ -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-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 h1:GGJVjV8waZKRHrgwvtH66z9ZGVurTD1MT0n1Bb+q4aM=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 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= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=

View File

@@ -74,6 +74,12 @@ func ErrorString(v ...interface{}) {
log.Output(2, color.Error.Render(fmt.Sprint(v...))) 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 系统级错误 //Fatal 系统级错误
func Fatal(v ...interface{}) { func Fatal(v ...interface{}) {
log.Output(2, color.Error.Render(fmt.Sprint(v...))) log.Output(2, color.Error.Render(fmt.Sprint(v...)))

32
mysignal/mysignal.go Normal file
View File

@@ -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 &notify{
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
}

View File

@@ -2,6 +2,7 @@ package myssh
import ( import (
"fmt" "fmt"
"io"
"net" "net"
"os" "os"
"time" "time"
@@ -38,36 +39,46 @@ func New(ip string, username string, password string, port ...int) (*Cli, error)
return cli, cli.connect() return cli, cli.connect()
} }
// Run 执行 shell脚本命令 // NewSession new session
func (c Cli) Run(shell string) (string, error) { func (c Cli) newSession() (*ssh.Session, error) {
if c.client == nil { if c.client == nil {
if err := c.connect(); err != nil { if err := c.connect(); err != nil {
return "", err return nil, err
} }
} }
session, err := c.client.NewSession() 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 { if err != nil {
return "", err return "", err
} }
defer session.Close() defer session.Close()
buf, err := session.CombinedOutput(shell)
buf, err := session.CombinedOutput(shell)
return string(buf), err return string(buf), err
} }
// RunTerminal 执行带交互的命令 // RunTerminal 执行带交互的命令
func (c *Cli) RunTerminal(shell string) error { func (c *Cli) RunTerminal(shell string) error {
if c.client == nil { session, err := c.newSession()
if err := c.connect(); err != nil {
return err
}
}
session, err := c.client.NewSession()
if err != nil { if err != nil {
return err return err
} }
defer session.Close() defer session.Close()
return c.runTerminalSession(session, shell)
}
// runTerminalSession 执行带交互的命令
func (c *Cli) runTerminalSession(session *ssh.Session, shell string) error {
fd := int(os.Stdin.Fd()) fd := int(os.Stdin.Fd())
oldState, err := terminal.MakeRaw(fd) oldState, err := terminal.MakeRaw(fd)
if err != nil { if err != nil {
@@ -99,15 +110,30 @@ func (c *Cli) RunTerminal(shell string) error {
return nil return nil
} }
// Terminal 进入终端 // EnterTerminal 完全进入终端
func (c Cli) Terminal() error { func (c Cli) EnterTerminal() error {
session, err := c.client.NewSession() session, err := c.newSession()
if err != nil { if err != nil {
return err return err
} }
defer session.Close() 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()) fd := int(os.Stdin.Fd())
oldState, err := terminal.MakeRaw(fd) oldState, err := terminal.MakeRaw(fd)
if err != nil { if err != nil {
@@ -115,9 +141,9 @@ func (c Cli) Terminal() error {
} }
defer terminal.Restore(fd, oldState) defer terminal.Restore(fd, oldState)
session.Stdout = os.Stdout session.Stdout = w
session.Stderr = os.Stdin session.Stderr = os.Stdin
session.Stdin = os.Stdin session.Stdin = r
termWidth, termHeight, err := terminal.GetSize(fd) termWidth, termHeight, err := terminal.GetSize(fd)
if err != nil { if err != nil {

View File

@@ -7,12 +7,12 @@ import (
) )
func TestMain(t *testing.T) { 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 { if err != nil {
fmt.Println("err", err) fmt.Println("err", err)
} }
output, err := c.Run("free -h") output, err := c.Run("ls")
fmt.Printf("%v\n%v", output, err) // 返回字符串 fmt.Printf("%v\n%v", output, err) // 返回字符串
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)

69
myssh/reader.go Normal file
View File

@@ -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)
}

42
myssh/write.go Normal file
View File

@@ -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)
}
}()
}