从Golang执行Bash脚本

huangapple go评论153阅读模式
英文:

Executing a Bash Script from Golang

问题

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

使用标准的os/exec方法似乎并不直接:尝试输入"./script.sh"或将脚本内容加载到字符串中作为exec函数的参数都不起作用。

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

OIFS=$IFS;
IFS=",";

# 填写你的详细信息
dbname=testDB
host=localhost:27017
collection=testCollection
exportTo=../csv/

# 获取逗号分隔的键列表。通过查看集合中的第一个文档并获取其键集来完成此操作
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`;
# 现在使用具有键集的mongoexport将集合导出为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文件的路径或实际内容 - 两者都不起作用。

有任何想法如何实现这一点吗?

英文:

I am trying to figure out a way to execute a script (.sh) file from Golang. I have found a couple of easy ways to execute commands (e.g. os/exec), but what I am looking to do is to execute an entire sh file (the file sets variables etc.).

Using the standard os/exec method for this does not seem to be straightforward: both trying to input "./script.sh" and loading the content of the script into a string do not work as arguments for the exec function.

for example, this is an sh file that I want to execute from Go:

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;

from the Go program:

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

where mongoToCsvSH can be either the path to the sh or the actual content - both do not work.

Any ideas how to achieve this?

答案1

得分: 60

要使您的Shell脚本可以直接运行,您需要:

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

  2. 您需要将其设置为可执行,即chmod +x script

如果您不想这样做,那么您将需要使用脚本的路径执行/bin/sh

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

For your shell script to be directly runnable you have to:

  1. Start it with #!/bin/sh (or #!/bin/bash, etc).

  2. You have to make it executable, aka chmod +x script.

If you don't want to do that, then you will have to execute /bin/sh with the path to the script.

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

答案2

得分: 12

这对我有效

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

This worked for me

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
}

答案3

得分: 6

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

英文:

You need to execute /bin/sh and pass the script itself as an argument.

答案4

得分: 1

这允许您传递参数,并在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("执行命令:", 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)
英文:

This allows you to pass the arguments as well as get the output of the script in the Stdout or Stderr.

import (
	&quot;github.com/sirupsen/logrus&quot;
	&quot;os&quot;
	&quot;os/exec&quot;
)

func Execute(script string, command []string) (bool, error) {

	cmd := &amp;exec.Cmd{
		Path:   script,
		Args:   command,
		Stdout: os.Stdout,
		Stderr: os.Stderr,
	}

	c.logger.Info(&quot;Executing command &quot;, cmd)

	err := cmd.Start()
	if err != nil {
		return false, err
	}

	err = cmd.Wait()
	if err != nil {
		return false, err
	}

	return true, nil
}

Calling example:

command := []string{
	&quot;/&lt;path&gt;/yourscript.sh&quot;,
	&quot;arg1=val1&quot;,
	&quot;arg2=val2&quot;,
}

Execute(&quot;/&lt;path&gt;/yourscript.sh&quot;, command)

huangapple
  • 本文由 发表于 2014年9月14日 22:25:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/25834277.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定