链接shell命令golang

I'm trying to run a shell script from my go program. I want to start up a mongo instance and then remove some data. So the shell script would look something like this:

mongo

use test-db

db.user.remove({"id": 1})

I initially tried just using the exec.Command package but it doesn't chain the commands so the mongo db closes and I can't run the other commands:

cmd := exec.Command("mongo", "test-db")
cmd.Start()
cmd1 := exec.Command("db.remove({\"id\": 1})")
cmd1.Run()
cmd.Wait()

The next thing I tried is creating a variable and trying to execute that via sh:

var script = `
 #!/bin/bash

mongo

use test-db

db.user.remove({"id": 1})
`

and executing exec.Command("sh", script)

I know I can create a .sh file but I don't want to do that is there any way to chain commands in go so the mongo db doesn't close and I can execute the other commands?

You seem to misunderstand how processes (such as interpreters and shells, including—it appearsmongodb as well) work with their so-called standard streams: while the "test-db" is indeed an argument to pass to a mongodb process to be created on its command-line, the db.user.remove({"id": 1}) is the text that spawned mongodb instance is supposed to read from its standard input stream.

So basically you need this:

import (
    "os/exec"
    "strings"
)

cmd := exec.Command("mongo", "test-db")
cmd.Stdin = strings.NewReader(`db.user.remove({"id": 1})
`)
err := cmd.Run()
// Check for an error

To explain how this works, let's cite the manual:

Stdin specifies the process's standard input.
If Stdin is nil, the process reads from the null device (os.DevNull).
If Stdin is an *os.File, the process's standard input is connected directly to that file.
Otherwise, during the execution of the command a separate goroutine reads from Stdin and delivers that data to the command over a pipe. In this case, Wait does not complete until the goroutine stops copying, either because it has reached the end of Stdin (EOF or a read error) or because writing to the pipe returned an error.
Stdin io.Reader

So basically you create an object which takes a string and provides something implementing io.Reader and "wire" it to the standard input of the process about to be created. Once the process starts, os/exec will make sure to spawn a goroutine which will shovel data between your string and the running mongodb instance—as if you would start mongodb by hand and typed that string onto its standard input stream directly.

Note that you also might need to check what mongodb generates on its standard output streams—especially stderr,—because if it encounters any errors while executing the script you have submitted to it, it will likely report them there.