Problem: Execute an external process with a customized environment.
Solution: The Go by Example site has as an example demonstrating how to spawn an external process and how exec a process. Those two examples provide a great starting point. Below, we’ll take it a step further to modify the environment.
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
)
// In this example `messageId` is a value that
// needs to be stored in an environment variable to be
// used by the command that's going to be executed
func doIt(messageId string) error {
binary, err := exec.LookPath("print_env.sh")
if err != nil {
return err
}
cmd := exec.Command(binary)
env := os.Environ()
env = append(env, fmt.Sprintf("MESSAGE_ID=%s", messageId))
cmd.Env = env
cmdOut, _ := cmd.StdoutPipe()
//cmdErr, _ := cmd.StderrPipe()
startErr := cmd.Start()
if startErr != nil {
return startErr
}
// read stdout and stderr
stdOutput, _ := ioutil.ReadAll(cmdOut)
//errOutput, _ := ioutil.ReadAll(cmdErr)
fmt.Printf("STDOUT: %s\n", stdOutput)
//fmt.Printf("ERROUT: %s\n", errOutput)
err = cmd.Wait()
return err
}
func main() {
messageId := "abc123"
err := doIt(messageId)
if err != nil {
fmt.Printf("Error: %v\n", err)
}
}
The doIt
function is where the magic happens. First, a exec.Command
is
created. Next, we grab a copy of the environment using os.Environ()
. The
environment is a slice of strings so we append another string, in the correct
format, containing the environment variable we want to add, MESSAGE_ID
.
The rest of the code sets up reading stdout (and stderr, though I commented )
and executing the command. If you run the program, you’ll see in the output
that MESSAGE_ID
was set to abc123
(as passed into the doIt
function).
Simple, right?