【问题标题】:Executing a Bash Script from Golang从 Golang 执行 Bash 脚本
【发布时间】:2014-11-08 04:00:21
【问题描述】:

我正在尝试找出一种从 Golang 执行脚本 (.sh) 文件的方法。我找到了几种执行命令的简单方法(例如 os/exec),但我想做的是执行整个 sh 文件(文件设置变量等)。

为此使用标准的 os/exec 方法似乎并不简单:尝试输入“./script.sh”和将脚本内容加载到字符串中都不能作为 exec 函数的参数。

例如,这是一个我想从 Go 执行的 sh 文件:

OIFS=$IFS;
IFS=",";

# fill in your details here
dbname=testDB
host=localhost:27017
collection=testCollection
exportTo=../csv/

# get comma separated list of keys. do this by peeking into the first document in the collection and get his set of keys
keys=`mongo "$host/$dbname" --eval "rs.slaveOk();var keys = []; for(var key in db.$collection.find().sort({_id: -1}).limit(1)[0]) { keys.push(key); }; keys;" --quiet`;
# now use mongoexport with the set of keys to export the collection to csv
mongoexport --host $host -d $dbname -c $collection --fields "$keys" --csv --out $exportTo$dbname.$collection.csv;

IFS=$OIFS;

来自 Go 程序:

out, err := exec.Command(mongoToCsvSH).Output()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("output is %s\n", out)

其中 mongoToCsvSH 可以是 sh 的路径或实际内容 - 两者都不起作用。

任何想法如何实现这一目标?

【问题讨论】:

    标签: bash go


    【解决方案1】:

    要让您的 shell 脚本直接运行,您必须:

    1. #!/bin/sh(或#!/bin/bash等)开头。

    2. 您必须使其可执行,即chmod +x script

    如果您不想这样做,则必须使用脚本路径执行/bin/sh

    cmd := exec.Command("/bin/sh", mongoToCsvSH)
    

    【讨论】:

    • 谢谢。这似乎工作。但是现在我有一个不同的问题 - 虽然脚本需要大约 1 分钟才能运行,但程序不会等待它完成运行。所以在没有实际编写导出的情况下继续执行..有什么想法吗?
    • @orcaman 你是怎么运行它的? exec.Command("/bin/sh", mongoToCsvSH).Output()?
    • 是的。问题是,在继续下一行之前,我必须等待这个 sh 导出文件。
    • 我们可以在上面的例子中将参数传递给 mongoToCsvSH 吗?
    • @BenyaminJafari 根据 Richard Bright 的回答,情况似乎如此。 (添加这个主要是为了未来的读者)
    【解决方案2】:

    这对我有用

    func Native() string {
        cmd, err := exec.Command("/bin/sh", "/path/to/file.sh").Output()
        if err != nil {
        fmt.Printf("error %s", err)
        }
        output := string(cmd)
        return output
    }
    

    【讨论】:

    • 当 /path/to/file.sh 需要参数时添加参数怎么办?
    【解决方案3】:

    您需要执行/bin/sh 并将脚本本身作为参数传递。

    【讨论】:

      【解决方案4】:

      这允许您传递参数以及在StdoutStderr 中获取脚本的输出。

      import (
          "github.com/sirupsen/logrus"
          "os"
          "os/exec"
      )
      
      func Execute(script string, command []string) (bool, error) {
      
          cmd := &exec.Cmd{
              Path:   script,
              Args:   command,
              Stdout: os.Stdout,
              Stderr: os.Stderr,
          }
      
          c.logger.Info("Executing command ", cmd)
      
          err := cmd.Start()
          if err != nil {
              return false, err
          }
      
          err = cmd.Wait()
          if err != nil {
              return false, err
          }
      
          return true, nil
      }
      

      调用示例:

      command := []string{
          "/<path>/yourscript.sh",
          "arg1=val1",
          "arg2=val2",
      }
      
      Execute("/<path>/yourscript.sh", command)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多