5

I need to run multiple commands in a single ssh session:

// Define the client configuration
config := &ssh.ClientConfig{
    User: USERNAME,
    Auth: []ssh.AuthMethod{
        ssh.PublicKeys(pem),
    },
}

// Connect to the machine
 client, err := ssh.Dial("tcp", HOSTNAME + ":" + PORT, config)
 if err != nil {
    panic("Failed to dial: " + err.Error())
}

// Create a session
session, err := client.NewSession()
if err != nil {
    panic("Failed to create session: " + err.Error())
}
defer session.Close()

// Start running commands!
var output bytes.Buffer
session.Stdout = &output

// 1)  Login to swarm registry
fmt.Println("Logging into swarm registry...")
if err := session.Run("docker login ..."); err != nil {
    panic("Failed to login to swarm registry: " + err.Error())
}
fmt.Println(output.String())

// 2)  List all of the docker processes
fmt.Println("List swarm processes...")
if err := session.Run("docker ps"); err != nil {    // <-------- FAILS HERE
    panic("Failed to list swarm processes: " + err.Error())
}
fmt.Println(output.String())

I read through the source file (session.go) and for the Session.Run command and it says:

A Session only accepts one call to Run, Start, Shell, Output, or CombinedOutput.

For my use case I need to issue the first command to log the session in, and then issue subsequent commands once I am logged in.

Is there an alternate way to run multiple commands using the same ssh session?

3
  • have you tried screen tecmint.com/screen-command-examples-to-manage-linux-terminals Commented Nov 18, 2016 at 18:57
  • The only way to execute multiple commands in a single session is to execute them together in a shell script, or interactively by parsing the shell output and writing to the input. This is the same as if you were using ssh on the command line. Commented Nov 18, 2016 at 19:02
  • @Tyler: interactively using the remote shell isn't really advised, it's more of a last resort option, and one usually uses something like "expect" for that. As for sending a series of commands in a script, what example do you need? You have it implemented here already, just send the text to be interpreted by the remote shell (remember, ssh is just a remote "secure shell", not a general RPC system) Commented Nov 18, 2016 at 19:16

1 Answer 1

3

Thanks to @JimB I am now doing this instead:

// Create a single command that is semicolon seperated
commands := []string{
    "docker login",
    "docker ps",
}
command := strings.Join(commands, "; ")

And then running it the same as before:

if err := session.Run(command); err != nil {
    panic("Failed to run command: " + command + "\nBecause: " + err.Error())
}
fmt.Println(output.String())
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.