码迷,mamicode.com
首页 > 其他好文 > 详细

Go执行远程ssh命令

时间:2018-01-11 15:49:30      阅读:799      评论:0      收藏:0      [点我收藏+]

标签:==   func   height   defer   input   last   nec   def   结果   

使用包:golang.org/x/crypto/ssh

以下封装一个发送命令的Cli结构体

type Cli struct {
    IP         string      //IP地址
    Username   string      //用户名
    Password   string      //密码
    Port       int         //端口号
    client     *ssh.Client //ssh客户端
    LastResult string      //最近一次Run的结果
}

//创建命令行对象
//@param ip IP地址
//@param username 用户名
//@param password 密码
//@param port 端口号,默认22
func New(ip string, username string, password string, port ...int) *Cli {
    cli := new(Cli)
    cli.IP = ip
    cli.Username = username
    cli.Password = password
    if len(port) <= 0 {
        cli.Port = 22
    } else {
        cli.Port = port[0]
    }
    return cli
}

//执行shell
//@param shell shell脚本命令
func (c Cli) Run(shell string) (string, error) {
    if c.client == nil {
        if err := c.connect(); err != nil {
            return "", err
        }
    }
    session, err := c.client.NewSession()
    if err != nil {
        return "", err
    }
    defer session.Close()
    buf, err := session.CombinedOutput(shell)

    c.LastResult = string(buf)
    return c.LastResult, err
}

测试执行shell代码

    cli := New("IP", "用户名", "密码", 端口号)
    output, err := cli.Run("free -h")
    fmt.Printf("%v\n%v", output, err)

还有类似top或者vim的命令是需要交互的,可以利用包golang.org/x/crypto/ssh/terminal实现

再封装一个方法RunTerminal

//执行带交互的命令
func (c *Cli) RunTerminal(shell string, stdout, stderr io.Writer) error {
    if c.client == nil {
        if err := c.connect(); err != nil {
            return err
        }
    }
    session, err := c.client.NewSession()
    if err != nil {
        return err
    }
    defer session.Close()

    fd := int(os.Stdin.Fd())
    oldState, err := terminal.MakeRaw(fd)
    if err != nil {
        panic(err)
    }
    defer terminal.Restore(fd, oldState)

    session.Stdout = stdout
    session.Stderr = stderr
    session.Stdin = os.Stdin

    termWidth, termHeight, err := terminal.GetSize(fd)
    if err != nil {
        panic(err)
    }
    // Set up terminal modes
    modes := ssh.TerminalModes{
        ssh.ECHO:          1,     // enable echoing
        ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
        ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
    }

    // Request pseudo terminal
    if err := session.RequestPty("xterm-256color", termHeight, termWidth, modes); err != nil {
        return err
    }

    session.Run(shell)
    return nil
}

测试RunTerminal方法

    cli := New("IP", "用户名", "密码", 端口号)
    cli.RunTerminal("top", os.Stdout, os.Stdin)

 

Go执行远程ssh命令

标签:==   func   height   defer   input   last   nec   def   结果   

原文地址:https://www.cnblogs.com/chenqionghe/p/8267326.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!