dsfsad089111
dsfsad089111
2019-03-09 00:22

在程序化Shell命令执行中嵌入环境变量

已采纳

I am in a situation where I am trying to execute a shell command, but have its arguments be interpreted as environment variables properly.

For example, when I type the following into the terminal

ls $GOPATH

Bash interprets and expands the variable $GOPATH, and lists the contents of the $GOPATH directory. I am trying to do a similar thing with Golang's programmatic shell execution.

I have the following code.

package main

import (
    "bytes"
    "fmt"
    "log"
    "os"
    "os/exec"
)

func main() {
    cmd := exec.Command("echo", "$TESTVAR")

    cmd.Env = append(os.Environ(),
        "TESTVAR=this_is_a_test",
    )

    var outBuff bytes.Buffer
    var errBuff bytes.Buffer

    cmd.Stdout = &outBuff
    cmd.Stderr = &errBuff

    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }

    fmt.Println(outBuff.String()) // empty
    fmt.Println(errBuff.String()) // empty
}

This program outputs

$ go run test.go
$TESTVAR

Does anyone have any idea how to make the exec library interpret $TESTVAR as an environment variable as opposed to a string literal? Thanks in advance!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • dtd14883 dtd14883 2年前

    Replace

    cmd := exec.Command("echo", "$TESTVAR")
    

    with

    cmd := exec.Command("sh", "-c", "echo $TESTVAR")
    
    点赞 评论 复制链接分享
  • dream1849 dream1849 2年前

    Bash and other shells interprets and expands variables, but the application is not executing Bash.

    The application is executing the echo command. The echo command, like most other commands, does not expand environment variables in its arguments.

    You can either run Bash as shown in another answer or expand environment variables on your own. Here's how to use os.Expand function to do this:

    func newCommandEnv(env []string, cmd string, args ...string) *exec.Cmd {
        m := map[string]string{}
        for _, e := range env {
            if i := strings.Index(e, "="); i >= 0 {
                m[e[:i]] = e[i+1:]
            }
        }
        fn := func(placeholder string) string {
            return m[placeholder]
        }
        for i, a := range args {
            args[i] = os.Expand(a, fn)
        }
        fmt.Println(args)
        c := exec.Command(cmd, args...)
        c.Env = env
        return c
    }
    
    点赞 评论 复制链接分享