是否可以捕获外部命令设置的环境变量?

时间:2018-02-27 03:48:40

标签: go

我有一个脚本(在Windows上),它设置了许多环境变量。我想在Go中执行此脚本,以便为后续调用二进制文件设置环境变量。

这样的事情:

cmd1 := exec.Command("setup_env.bat")
cmd.Run()

// other_command.exe relies on environment variables
// set by setup_env.bat
cmd2 := exec.Command("some_binary.exe")
cmd2.Env = cmd1.Env
cmd2.Run()

但是这不起作用,因为调用cmd1.Envcmd1.Run()为空(cmd1中设置的环境变量似乎不会传播到cmd1.Env })。在致电os.Environ()后,cmd1.Run()似乎也未受影响。

如果您对我为何要这样做感到好奇,我会尝试自动执行通常要求用户拨打setup_env.bat后跟other_command.exe的任务在命令提示符下。我不拥有setup_env.bat,它可能会经常更改,因此我无法在Go中自行设置环境变量。

1 个答案:

答案 0 :(得分:0)

我设法使用以下代码生成所需的结果:

cmd := exec.Command("setup_env.bat", "&&", "some_binary.exe")
cmd.Run()

我还发现在使用stdout打印环境后,可以通过捕获SET来手动解析环境变量。例如:

func getEnv(command string) ([]string, error) {
    cmd := exec.Command(command, "&&", "SET")
    out, _ := cmd.StdoutPipe()

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

    rawEnv, _ := ioutil.ReadAll(out)

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

    env := strings.Split(string(rawEnv), "\r\n")
    return env[:len(env)-1], nil
}

// ...

cmd := exec.Command("some_binary.exe")
env, err := getEnv("setup_env.bat")
if err != nil {
    log.Fatal(err)
}
cmd.Env = env // or os.Setenv(...) if you need it in current context
cmd.Run()