【发布时间】:2018-12-03 13:30:10
【问题描述】:
我想在 Go 中运行以下代码:
out, err := exec.Command("echo", "$PATH").Output()
结果是:
$PATH
而不是“PATH=/bin...”的预期值。
为什么?以及如何获得期望值?
【问题讨论】:
我想在 Go 中运行以下代码:
out, err := exec.Command("echo", "$PATH").Output()
结果是:
$PATH
而不是“PATH=/bin...”的预期值。
为什么?以及如何获得期望值?
【问题讨论】:
您的命令没有被 shell 解释,这就是预期的变量替换没有发生的原因。
...os/exec 包故意不调用系统 shell 并且不扩展任何 glob 模式或处理其他扩展, 管道,或通常由 shell 完成的重定向。
...
要扩展环境变量,请使用包 os 的 ExpandEnv。
所以要在你的例子中达到预期的结果:
out, err := exec.Command("echo", os.ExpandEnv("$PATH")).Output()
值得回顾一下用于获取环境变量并使用最适合您的特定用例的函数集:
func ExpandEnv(s string) string - ExpandEnv 根据当前环境变量的值替换字符串中的 ${var} 或 $var。对未定义变量的引用被空字符串替换。func Getenv(key string) string - Getenv 检索由键命名的环境变量的值。它返回值,如果变量不存在,该值将为空。要区分空值和未设置值,请使用 LookupEnv。func LookupEnv(key string) (string, bool) - LookupEnv 检索由键命名的环境变量的值。如果变量存在于环境中,则返回值(可能为空)并且布尔值为真。否则返回值为空,布尔值为 false。【讨论】:
os.LookupEnv 来捕获由于某种原因在环境中未设置 PATH 变量的情况。
从Go by Example: Environment Variables,您可以尝试(而不是系统命令echo)使用os.Getenv:
fmt.Println("PATH:", os.Getenv("PATH"))
【讨论】:
由于您使用的是 shell 命令,因此您需要提供 shell 来运行该命令。
cmd=exec.Command("/bin/sh","-c", "echo $PATH")
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
err := cmd.Run()
if err != nil {
panic(err)
}
【讨论】: