waigani
waigani

Reputation: 3580

Golang: execute text/template as bash script

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.

Upvotes: 3

Views: 3718

Answers (2)

Sean
Sean

Reputation: 1803

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.

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()
}

Upvotes: 6

atrn
atrn

Reputation: 92

Use bash -c... exec.Command("bash", "-c", bashScript).

Upvotes: -1

Related Questions