英文:
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 之间有什么区别,可能导致权限被拒绝的错误?
run
和 run2
之间有什么区别,使得其中一个可以工作而另一个不行?
编辑:使用 -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
,而你可能使用的是 bash
或 zsh
。
下面是一些方便的默认配置,可以用于配置你的 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论