douyu3145 2016-04-08 15:24
浏览 22
已采纳

链接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?

  • 写回答

1条回答 默认 最新

  • doulingna9420 2016-04-08 16:44
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效