I'm using go's ssh module, and I'm trying to pipe input from my program to the remote shell over stdin. This works as expected, printing Hello World
:
mySession := PrepareSession() // helper method to prepare a Connection and Session object
output, _ := mySession.Output("echo Hello World")
fmt.Println(output)
When I try to provide stdin input, however, it hangs on the line myStdin.Write("Hello World")
(I've confirmed this with a debugger):
mySession := PrepareSession()
myStdin, _ := mySession.StdinPipe()
myStdin.Write("Hello World")
output, _ := mySession.Output("cat /dev/stdin | echo")
fmt.Println(output)
Replacing myStdin.Write("Hello World")
with fmt.Fprint(myStdin, "Hello World")
yields the same problem.
Overall I just don't understand how pipes work in Go - how do I get the pipe to stop hanging when I feed input to it?
StdinPipe
is the standard input for the remote command, as mentioned in the docs.
Your second example attempts to write to stdin on the remote host without running a command. Since there is no remote command, there is no consumer for stdin, hanging forever.
Instead, you should do something similar to the Output method:
func (s *Session) Output(cmd string) ([]byte, error) {
if s.Stdout != nil {
return nil, errors.New("ssh: Stdout already set")
}
var b bytes.Buffer
s.Stdout = &b
err := s.Run(cmd) <---- you need to run a command on the remote host.
return b.Bytes(), err
}