Golang:将text/template作为bash脚本执行

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

Golang: execute text/template as bash script

问题

给定以下代码:

import (
    "bytes"
    "code.google.com/p/go/src/pkg/text/template"
)

....

var tmp = template.Must(template.New("").Parse(`
    echo {{.Name}}
    echo {{.Surname}}
`[1:]))

var buf bytes.Buffer
tmp.Execute(&buf, struct{Name string, Surname: string}{"James","Dean"})
bashScript := string(buf)

// 现在,我该如何执行这个 bash 脚本?
magic.Execute(bashScript)

有没有一个神奇的函数可以将字符串作为一个 bash 脚本执行?"os/exec".Command 只能一次执行一个命令。

英文:

Given the following:

   import(
   "bytes"
   "code.google.com/p/go/src/pkg/text/template"
   )

   ....

   var tmp = template.Must(template.New("").Parse(`
   echo {{.Name}}
   echo {{.Surname}}
   `[1:]))

   var buf bytes.Buffer
   tmp.Execute(&buf, struct{Name string, Surname: string}{"James","Dean"})
   bashScript = string(buf)
   
   // Now, how do I execute the bash script?
   magic.Execute(bashScript)

Is there a magic function that will execute the string as one bash script? "os/exec".Command can execute only one command at a time.

答案1

得分: 6

如果你想执行多个命令,尤其是同时执行多个命令,bash 不是最好的方法。可以使用 os/exec 和 goroutines。

如果你真的想运行一个 bash 脚本,这里有一个使用 os/exec 的示例。我假设你想要看到 bash 脚本的输出,而不是保存和处理它(但你可以很容易地使用 bytes.Buffer 来实现)。为了简洁起见,我在这里省略了所有的错误检查。完整版本的代码可以在这里找到

package main

import (
        "bytes"
        "io"
        "text/template"
        "os"
        "os/exec"
        "sync"
)

func main() {
        var tmp = template.Must(template.New("").Parse(`
echo {{.Name}}
echo {{.Surname}}
`[1:]))

        var script bytes.Buffer
        tmp.Execute(&script, struct {
                Name    string
                Surname string
        }{"James", "Dean"})

        bash := exec.Command("bash")
        stdin, _ := bash.StdinPipe()
        stdout, _ := bash.StdoutPipe()
        stderr, _ := bash.StderrPipe()

        wait := sync.WaitGroup{}
        wait.Add(3)
        go func () {
                io.Copy(stdin, &script)
                stdin.Close()
                wait.Done()
        }()
        go func () {
                io.Copy(os.Stdout, stdout)
                wait.Done()
        }()
        go func () {
                io.Copy(os.Stderr, stderr)
                wait.Done()
        }()

        bash.Start()
        wait.Wait()
        bash.Wait()
}
英文:

If you want to execute more than one command, especially more than one at a time, bash is not the best way to do that. Use os/exec and goroutines.

If you really want to run a bash script, here's an example using os/exec. I assumed you wanted to see the output of the bash script, rather than save it and process it (but you can easily do that with a bytes.Buffer). I've removed all the error checking here for brevity. The full version with error checking is here.

<pre>
package main

import (
"bytes"
"io"
"text/template"
"os"
"os/exec"
"sync"
)

func main() {
var tmp = template.Must(template.New("").Parse(
echo {{.Name}}
echo {{.Surname}}
[1:]))

    var script bytes.Buffer
    tmp.Execute(&amp;script, struct {
            Name    string
            Surname string
    }{&quot;James&quot;, &quot;Dean&quot;})

    bash := exec.Command(&quot;bash&quot;)
    stdin, _ := bash.StdinPipe()
    stdout, _ := bash.StdoutPipe()
    stderr, _ := bash.StderrPipe()

    wait := sync.WaitGroup{}
    wait.Add(3)
    go func () {
            io.Copy(stdin, &amp;script)
            stdin.Close()
            wait.Done()
    }()
    go func () {
            io.Copy(os.Stdout, stdout)
            wait.Done()
    }()
    go func () {
            io.Copy(os.Stderr, stderr)
            wait.Done()
    }()

    bash.Start()
    wait.Wait()
    bash.Wait()

}
</pre>

答案2

得分: -1

使用 bash -c... exec.Command("bash", "-c", bashScript)

英文:

Use bash -c... exec.Command(&quot;bash&quot;, &quot;-c&quot;, bashScript).

huangapple
  • 本文由 发表于 2014年8月13日 11:50:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/25277739.html
匿名

发表评论

匿名网友

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

确定