加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Golang ssh – 如何在同一个会话上运行多个命令?

发布时间:2020-12-16 19:22:32 所属栏目:大数据 来源:网络整理
导读:我试图通过 ssh运行多个命令,但似乎 Session.Run每个会话只允许一个命令(除非我错了).我想知道如何绕过这个限制并重用会话或发送一系列命令. 原因是我需要在下一个命令(sh /usr/bin/myscript.sh)的同一个会话中运行sudo su 虽然针对您的具体问题,您可以轻松
我试图通过 ssh运行多个命令,但似乎 Session.Run每个会话只允许一个命令(除非我错了).我想知道如何绕过这个限制并重用会话或发送一系列命令.
原因是我需要在下一个命令(sh /usr/bin/myscript.sh)的同一个会话中运行sudo su
虽然针对您的具体问题,您可以轻松运行sudo /path/to/script.sh,但令我震惊的是,没有一种简单的方法可以在同一个会话中运行多个命令,所以我想出了一些 hack,YMMV:
func MuxShell(w io.Writer,r io.Reader) (chan<- string,<-chan string) {
    in := make(chan string,1)
    out := make(chan string,1)
    var wg sync.WaitGroup
    wg.Add(1) //for the shell itself
    go func() {
        for cmd := range in {
            wg.Add(1)
            w.Write([]byte(cmd + "n"))
            wg.Wait()
        }
    }()
    go func() {
        var (
            buf [65 * 1024]byte
            t   int
        )
        for {
            n,err := r.Read(buf[t:])
            if err != nil {
                close(in)
                close(out)
                return
            }
            t += n
            if buf[t-2] == '$' { //assuming the $PS1 == 'sh-4.3$'
                out <- string(buf[:t])
                t = 0
                wg.Done()
            }
        }
    }()
    return in,out
}

func main() {
    config := &ssh.ClientConfig{
        User: "kf5",Auth: []ssh.AuthMethod{
            ssh.Password("kf5"),},}
    client,err := ssh.Dial("tcp","127.0.0.1:22",config)
    if err != nil {
        panic(err)
    }

    defer client.Close()
    session,err := client.NewSession()

    if err != nil {
        log.Fatalf("unable to create session: %s",err)
    }
    defer session.Close()

    modes := ssh.TerminalModes{
        ssh.ECHO:          0,// disable echoing
        ssh.TTY_OP_ISPEED: 14400,// input speed = 14.4kbaud
        ssh.TTY_OP_OSPEED: 14400,// output speed = 14.4kbaud
    }

    if err := session.RequestPty("xterm",80,40,modes); err != nil {
        log.Fatal(err)
    }

    w,err := session.StdinPipe()
    if err != nil {
        panic(err)
    }
    r,err := session.StdoutPipe()
    if err != nil {
        panic(err)
    }
    in,out := MuxShell(w,r)
    if err := session.Start("/bin/sh"); err != nil {
        log.Fatal(err)
    }
    <-out //ignore the shell output
    in <- "ls -lhav"
    fmt.Printf("ls output: %sn",<-out)

    in <- "whoami"
    fmt.Printf("whoami: %sn",<-out)

    in <- "exit"
    session.Wait()
}

如果你的shell提示符不是以$($后跟空格)结尾,那么这将是死锁,因此为什么它是一个hack.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读