提问人:404 提问时间:10/19/2023 最后编辑:404 更新时间:10/19/2023 访问量:46
exec 的可执行决议。命令 + 路径
Executable Resolution for exec.Command + PATH
问:
具有非常相似的命令调用
cmdDirect := exec.Command("theExecutable")
cmdShell := exec.Command(os.GetEnv("SHELL"), "-c", "theExecutable")
两者都具有相同的环境设置
envWithPath := append(os.Environ(), fmt.Sprintf("PATH=/real/existing/path/to/theExecutable/holder:%s", os.GetEnv("PATH")))
cmdDirect.Env = envWithPath
cmdShell.Env = envWithPath
尽管如此,虽然按预期工作良好,但失败cmdShell
cmdDirect
exec: "theExecutable": executable file not found in $PATH
对于上述相同的环境设置,调用也是成功的
cmdWhich := exec.Command("which", "theExecutable")
正确返回/real/existing/path/to/theExecutable/holder/theExecutable
那么,造成这种差异的原因可能是什么呢?
P.S. 以及这两种方法肯定具有完全相同的设置。例如$PATH
exec.Command("env")
exec.Command(os.GetEnv("SHELL"), "-c", "env")
两个输出是否具有相同的序列PATH=....
感谢
答:
1赞
maxm
10/19/2023
#1
exec.Command
查找使用 PATH 的可执行文件的路径,而不是在 cmd 上设置的路径。exec.LookPath
如果您希望对特定可执行文件进行更可靠的查找(或像您一样生成子 shell),我建议设置为可执行文件的路径。Cmd.Path
评论
0赞
404
10/19/2023
啊!!伟大。谢谢。该行为非常符合您的描述。是否有任何捷径可以额外序列化/取消引用/转义引擎盖下的 args 切片?据我了解,它本身与“PATH”不同,应该只包含一个最终目标路径,不是吗?或者我可以使用自定义的“PATH”值即时解决它。我看不出明确提供它的方法。exec.Command(os.GetEnv("SHELL"), "-c", "command with args")
Cmd.Path
exec.LookPath
0赞
404
10/19/2023
或者组合真的足以满足一般需求吗?os.GetEnv("SHELL"), "-c"
cross shell
0赞
maxm
10/19/2023
是的,如果你这样做,你应该能够检查的值,它将是你尝试调用的可执行文件的绝对路径。如果它不是您期望的样子,您可以将其设置为其他内容。我同意没有办法控制正在访问的 PATH,如果您想对运行的内容进行非常精细的控制,我可能会考虑手动填充 Cmd。cmd, _ := exec.Command("theExecutable")
cmd.Path
exec.LookPath
评论
echo $PATH
PATH
cmd*.Env = append(
PATH
cmd*
Direct
Shell
PATH=