Golang的SSH

编程入门 行业动态 更新时间:2024-10-27 23:26:28
本文介绍了Golang的SSH - 如何在同一个会话上运行多个命令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我试图通过 ssh 运行多个命令,但似乎是 Session.Run 每个会话只允许一个命令(除非我错了) 。我想知道如何绕过这个限制,重新使用会话或发送一系列命令。 原因是我需要在同一个会话中使用下一个命令(sh /usr/bin/myscript.sh)运行 sudo su

解决方案

针对您的特定问题,您可以轻松运行 sudo /path/to/script.sh,这让我震惊,没有一种简单的方法在同一个会话中运行多个命令,所以我想出了一个 var wg(chan字符串,1) sync.WaitGroup wg.Add(1)//对于shell本身去func(){ for cmd:=范围在{ wg.Add(1) w.Write([] byte(cmd +\\\)) wg.Wait()} }() go func(){ var( buf [65 * 1024] byte t 为{n,err:= r.Read(buf [t:]) if err!= nil { close(in) close(out) return } t + = n if buf [t-2] =='$'{//假设$ PS1 ==' sh-4.3 $' out< - string(buf [:t])t = 0 wg.Done()} } }() return in,out } func main(){ config:=& ssh.ClientConfig { User:kf5 ,认证:[] 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(无法创建s ession:%s,err)} 推迟session.Close() 模式:= ssh.TerminalModes { ssh.ECHO:0,//禁用回显 ssh.TTY_OP_ISPEED:14400,//输入速度= 14.4kbaud ssh.TTY_OP_OSPEED:14400,//输出速度= 14.4kbaud } if err:= session.RequestPty(xterm,80,40,modes); err!= nil { log.Fatal(err)} $ bw,err:= session.StdinPipe() if err!= nil {恐慌(错误)} r,错误:= session.StdoutPipe() if err!= nil { panic(err)} in,out:= MuxShell(w,r) if err:= session.Start(/ bin / sh); err!= nil { log.Fatal(err)} < -out //忽略shell输出 in< - ls -lhav fmt.Printf(ls输出:%s \\\,< -out) in< - whoami fmt.Printf(whoami:%s \\ \\ n,< -out) in< - exit session.Wait()}

如果您的shell提示符不以 $ ($紧跟一个空格)结尾,死锁,因此它为什么是黑客。

I'm trying to run multiple commands through ssh but seems that Session.Run allows only one command per session ( unless I'm wrong). I'm wondering how can I bypass this limitation and reuse the session or send a sequence of commands. The reason is that I need to run sudo su within the same session with the next command ( sh /usr/bin/myscript.sh )

解决方案

While for your specific problem, you can easily run sudo /path/to/script.sh, it shock me that there wasn't a simple way to run multiple commands on the same session, so I came up with a bit of a 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: %s\n", <-out) in <- "whoami" fmt.Printf("whoami: %s\n", <-out) in <- "exit" session.Wait() }

If your shell prompt doesn't end with $ ($ followed by a space), this will deadlock, hence why it's a hack.

更多推荐

Golang的SSH

本文发布于:2023-08-05 11:24:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1305215.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Golang   SSH

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!