golang 1.19 错误“exec:“XXX“:cannot run executable found relative to current directory”

概观

        包执行运行外部命令。它包装os。StartProcess使重新映射stdin和stdout,用管道连接I/O以及进行其他调整变得更加容易。

        与来自C和其他语言的“系统”库调用不同,os/exec包有意不调用系统外壳,并且不扩展任何glob模式或处理通常由外壳完成的其他扩展、管道或重定向。这个包的行为更像C语言的“exec”系列函数。要扩展glob模式,要么直接调用shell,注意避免任何危险的输入,要么使用path/filepath包的Glob函数。要扩展环境变量,请使用软件包os的ExpandEnv。

        注意,这个包中的例子假设了一个Unix系统。它们不能在Windows上运行,也不能在golang.org和godoc.org使用的围棋场上运行。

当前目录中的可执行文件

        函数Command和LookPath按照主机操作系统的约定,在当前路径中列出的目录中查找程序。几十年来,操作系统都将当前目录包含在搜索中,默认情况下,有时是隐式的,有时是显式的。现代实践是,包含当前目录通常是意想不到的,并且经常导致安全问题。

        为了避免这些安全问题,从Go 1.19开始,这个包将不使用相对于当前目录的隐式或显式路径条目来解析程序。也就是说,如果你运行exec。LookPath("go "),它不会成功返回。/在Unix nor上继续。\go.exe,无论路径如何配置。相反,如果通常的路径算法会得到那个答案,这些函数会返回一个满足错误的错误err。Is(err,ErrDot)。

例如,考虑这两个程序片段:

path, err := exec.LookPath("prog")
if err != nil {
	log.Fatal(err)
}
use(path)

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

这些不会发现和运行。/prog或。\prog.exe,无论当前路径如何配置。

总是想从当前目录运行程序的代码可以重写为。/prog”而不是“prog”。

坚持包含相对路径项的结果的代码可以使用errors替代该错误。是检查:

path, err := exec.LookPath("prog")
if errors.Is(err, exec.ErrDot) {
	err = nil
}
if err != nil {
	log.Fatal(err)
}
use(path)

cmd := exec.Command("prog")
if errors.Is(cmd.Err, exec.ErrDot) {
	cmd.Err = nil
}
if err := cmd.Run(); err != nil {
	log.Fatal(err)
}

        将环境变量GODEBUG=execerrdot=0设置为0将完全禁用errdot的生成,从而为无法应用更有针对性的修复的程序临时恢复1.19版之前的行为。Go的未来版本可能会删除对该变量的支持。

        在添加此类覆盖之前,请确保您理解这样做的安全含义。看见Command PATH security in Go - The Go Programming Language了解更多信息。

(官方说明翻译)

官方说明地址exec package - os/exec - Go Packages

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值