I want to execute a go file which I will specify in a yaml config file and send it a Struct in bytes. How could I do this?
I thought that I could use Stdin and Stdout for this
But can’t figure it out Yaml config:
subscribers:
temp:
topics:
- pi/+/temp
action: ./temp/tempBinary
this is my code:
client.Subscribe(NewTopic(a), func(c *Client, msg Message) {
cmd := exec.Command(v.Action)
// I actually want to send [msg] to it so it can be used there
cmd.Stdin = bytes.NewReader(msg.Bytes())
if err := cmd.Start(); err != nil {
c.Logger.Infof("Error while executing action: %v", err)
} else {
c.Logger.Info("Executed command")
}
// I want to handle responses from the called binary
var out bytes.Buffer
cmd.Stdout = &out
c.Logger.Infof("Response: %v", out)
})
I can't figure out how exactly I could do this.
There is a good example of what you need at https://golang.org/pkg/os/exec/#example_Cmd_StdinPip, https://golang.org/pkg/os/exec/#example_Cmd_StdoutPipe and https://golang.org/pkg/io/ioutil/#example_ReadAll
A decent start would be something like:
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
defer stdin.Close()
io.WriteString(stdin, msg.String())
b, err := ioutil.ReadAll(stdout)
if err != nil {
log.Fatal(err)
}
c.Logger.Infof("Response %s", stdout)
But this solution doesn't even begin to handle edge cases such as pipes being closed early etc.
This video does a good job of talking through stuff like this: https://www.youtube.com/watch?v=LHZ2CAZE6Gs&feature=youtu.be&list=PL6