我处于一种试图执行shell命令的情况,但是其参数必须正确解释为环境变量。
例如,当我在终端中输入以下内容
ls $GOPATH
Bash解释并扩展变量$GOPATH
,并列出$GOPATH
目录的内容。我正在尝试对Golang的程序化Shell执行类似的操作。
我有以下代码。
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
}
该程序输出
$ go run test.go
$TESTVAR
有人知道如何使exec库将$ TESTVAR解释为环境变量而不是字符串文字吗?预先感谢!
答案 0 :(得分:2)
替换
cmd := exec.Command("echo", "$TESTVAR")
使用
cmd := exec.Command("sh", "-c", "echo $TESTVAR")
答案 1 :(得分:1)
Bash和其他shell解释和扩展变量,但是应用程序未执行Bash。
应用程序正在执行echo命令。与大多数其他命令一样,echo命令不会在其参数中扩展环境变量。
您可以运行Bash(如另一个答案所示),也可以自行扩展环境变量。使用os.Expand函数执行此操作的方法如下:
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
}