dsfsad089111
2019-03-09 00:22
浏览 189

在程序化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 2019-03-09 01:09
    已采纳

    Replace

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

    with

    cmd := exec.Command("sh", "-c", "echo $TESTVAR")
    
    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • dream1849 2019-03-09 05:00

    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
    }
    
    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题