在运行 Makefile 中的 go 命令时出现了权限被拒绝的错误。

huangapple go评论83阅读模式
英文:

Permission denied when running go from Makefile

问题

我正在经历一些奇怪的权限被拒绝的错误,但我不知道它们是从哪里引起的。

$ go run .
Hello from go
$ make run
go: 无法访问 go 文件: 权限被拒绝
make: *** [Makefile:2: run] 错误 127
$ make run2
echo "Make says hello" ; go run .
Make says hello
Hello from go
$ cat Makefile 
run:
	go run .

run2:
	echo "Make says hello" ; go run .
$ cat main.go 
package main

import "fmt"

func main() {
	fmt.Println("Hello from go")
}

我的终端是在运行 Ubuntu 22.04 的 bash。

我的 run 目标和直接运行 go 之间有什么区别,可能导致权限被拒绝的错误?

runrun2 之间有什么区别,使得其中一个可以工作而另一个不行?

编辑:使用 -d / --trace 运行 make

$ make -d run
<...snip...>
 无需重新生成目标文件 'Makefile'正在更新目标 'run'正在考虑目标文件 'run' 目标文件 'run' 不存在。
已完成目标文件 'run' 的前提条件。
必须重新生成目标 'run'go run .
make: go: 权限被拒绝
make: *** [Makefile:2: run] 错误 127
$ make --trace run
Makefile:2: 目标 'run' 不存在
go run .
make: go: 权限被拒绝
make: *** [Makefile:2: run] 错误 127
$ make --trace run2
Makefile:5: 目标 'run2' 不存在
echo "Make says hello"; go run .
Make says hello
Hello from go
英文:

I'm experiencing some weird permission denied errors that I have no idea where could be coming from.

$ go run .
Hello from go
$ make run
go run .
make: go: Permission denied
make: *** [Makefile:2: run] Error 127
$ make run2
echo "Make says hello" ; go run .
Make says hello
Hello from go
$ cat Makefile 
run:
	go run .

run2:
	echo "Make says hello" ; go run .
$ cat main.go 
package main

import "fmt"

func main() {
	fmt.Println("Hello from go")
}

My terminal is bash running on Ubuntu 22.04.

What is the difference between my run target and running go directly that can cause a permission denied error?

What's the difference between run and run2 that allow it to work in one but not in the other?

EDIT: Running make with -d / --trace

$ make -d run
<...snip...>
 No need to remake target 'Makefile'.
Updating goal targets....
Considering target file 'run'.
 File 'run' does not exist.
 Finished prerequisites of target file 'run'.
Must remake target 'run'.
go run .
make: go: Permission denied
make: *** [Makefile:2: run] Error 127
$ make --trace run
Makefile:2: target 'run' does not exist
go run .
make: go: Permission denied
make: *** [Makefile:2: run] Error 127
$ make --trace run2
Makefile:5: target 'run2' does not exist
echo "Make says hello"; go run .
Make says hello
Hello from go

答案1

得分: 7

这是由GNU make中的一个错误引起的(实际上是gnulib中的一个错误)。这意味着你的PATH中有一个名为go的_目录_(在包含go可执行文件的实际目录之前)。

所以,如果你的PATH中有一个_目录_ /usr/bin/go/.,并且你的PATH中包含/usr/bin,你就会遇到这个问题。

你应该检查你的PATH,确保删除任何包含这种子目录的目录。如果你无法从PATH中删除该目录(在PATH中需要包含子目录的目录是不常见的,但我猜可能是可能的),并且你无法将go目录重命名为其他名称,那么你将需要确保GNU make调用一个shell,方法是添加一个特殊字符。只需要使用;即可:

run:
         go run . ;
英文:

This is due to a bug in GNU make (actually it's a bug in gnulib). It means that you have a directory named go, in some directory on your PATH (before the actual directory containing the go executable).

So if you have a directory /usr/bin/go/. and you have /usr/bin on your PATH, you'll see this issue.

You should check your PATH and make sure to remove any directories that contain such subdirectories. If you can't remove that directory from your PATH (it's unusual to need directories containing subdirectories on your PATH but I guess it's possible) and you can't rename the go directory to something else, you'll have to ensure that GNU make invokes a shell, by adding a special character. Just ; is good enough:

run:
         go run . ;

答案2

得分: 1

你遇到的问题可能是由于你的 shell 环境和 Makefile 执行的 shell 环境不同造成的。例如,如果你为 go 设置了一个别名,在 Makefile 中是看不到这个别名的;或者如果你在 shell 的 rc 文件中设置了自定义路径,在 Makefile 中也是看不到的。很难猜测差异可能出现在哪里。

你可以尝试在你的 Makefile 中调试这个问题,尝试执行以下命令:

echo $(PATH)
command -v go

然后在你的 shell 中运行相同的命令并比较结果。

请注意,Makefile 的默认 shell 是 /bin/sh,而你可能使用的是 bashzsh

下面是一些方便的默认配置,可以用于配置你的 Makefile 构建:

LANG=en_US.UTF-8
SHELL=/bin/bash
.SHELLFLAGS=--norc --noprofile -e -u -o pipefail -c
英文:

The issue you're experiencing is likely due to different environment between your shell and shell executed by Makefile. If for example you have a shell alias for go this alias is not visible to Makefile or if you have a custom path in you're shell rc file it's not visible to Makefile. It's hard to guess where the difference might be.

You might want to try debug the issue by trying following in your Makefile:

echo $(PATH)
command -v go

and run the same commands in your shell and compare results.

Note that the default shell for Makefile is /bin/sh whereas you probably have bash or zsh.

Here's some handy defaults to configure your Makefile build:

LANG=en_US.UTF-8
SHELL=/bin/bash
.SHELLFLAGS=--norc --noprofile -e -u -o pipefail -c

huangapple
  • 本文由 发表于 2022年9月30日 20:24:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/73908737.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定