我试图通过
ssh运行多个命令,但似乎
Session.Run每个会话只允许一个命令(除非我错了).我想知道如何绕过这个限制并重用会话或发送一系列命令.
原因是我需要在下一个命令(sh /usr/bin/myscript.sh)的同一个会话中运行sudo su
原因是我需要在下一个命令(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: %s\n",<-out) in <- "whoami" fmt.Printf("whoami: %s\n",<-out) in <- "exit" session.Wait() }
如果你的shell提示符不是以$($后跟空格)结尾,那么这将是死锁,因此为什么它是一个hack.