go install 报 permission denied 的根本原因是 gopath 未生效,导致 go 工具链回退至只读的 goroot 目录;需检查 go env gopath、path 是否包含 $gopath/bin,并确保 gopath 为绝对路径且正确加载于 shell 配置中。

go install 报 permission denied 是因为 GOPATH 没生效
根本原因不是权限设置错了,而是 Go 工具链压根没读到你设的 GOPATH。它 fallback 到了 GOROOT 下的 pkg 或 bin 目录(比如 /usr/local/go/pkg),而这些路径普通用户不可写。
验证方法很简单:go env GOPATH 输出为空或不是你预期的路径,就说明变量没被正确加载;再看 echo $PATH 是否包含 $GOPATH/bin —— 如果没加进去,go install 生成的二进制即使放对了地方,你也运行不了。
-
GOPATH必须是绝对路径,不能含~(shell 不一定展开) - 不要在命令行用
export GOPATH=...临时设置,关掉终端就失效 - 确认你改的是当前 shell 的配置文件:
~/.bashrc(bash)、~/.zshrc(zsh),改完必须source ~/.zshrc - 如果用 VS Code 或 JetBrains 系列 IDE,它们可能不读 shell 配置,需重启 IDE 或手动在设置里指定环境变量
GOROOT 通常不用手动设,但设错会直接让 go 命令启动失败
GOROOT 是 Go 安装根目录,不是 bin 子目录。官方包安装后(如 /usr/local/go),Go 能自动识别,强行设反而容易出问题。
只有两种情况才需要显式设置:Go 装在非标路径(如 /opt/go1.22),或你要切换多个 Go 版本(配合 g 或 gvm)。
- 错误写法:
GOROOT=/usr/local/go/bin❌(多了/bin) - 错误写法:
GOROOT=~/go❌(波浪号在某些上下文不展开) - 正确写法:
export GOROOT=/usr/local/go✅ - 验证:运行
go env GOROOT,输出应与你设置的一致;若为空,go version可能直接报错或返回异常路径
GOBIN 显式设置比依赖默认值更可靠
GOBIN 控制 go install 输出可执行文件的位置。默认是 $GOPATH/bin,但如果你只设了 GOPATH 却忘了把 $GOPATH/bin 加进 PATH,或者 GOPATH 被工具链忽略,GOBIN 就成了最后一道防线。
尤其在 CI/CD 或多用户共享机器场景下,显式声明能避免行为漂移。
- 推荐写法:
export GOBIN=$HOME/go/bin,然后确保$GOBIN在PATH中靠前位置 - 不要依赖
go install自动创建bin目录:先手动mkdir -p $GOBIN,避免首次运行失败 - 如果
GOBIN和GOPATH指向不同磁盘(比如GOBIN在 SSD、GOPATH在 HDD),注意go mod download缓存仍走$GOPATH/pkg/mod,性能瓶颈可能不在GOBIN
Go Modules 开启后,GOPATH/src 不再是项目必需位置
从 Go 1.16 起,GO111MODULE=on 是默认行为。这意味着:go build 和 go run 不再扫描 $GOPATH/src,只要当前目录有 go.mod,项目就能在任意路径运行。
但 GOPATH 并未废弃——go install、go get(无 @version 时)、以及所有命令行工具(如 gopls、stringer)的安装目标,依然由 GOPATH 和 GOBIN 决定。
- 新项目不必放进
$GOPATH/src/github.com/user/repo,直接mkdir myproj && cd myproj && go mod init myproj - 模块缓存仍存在
$GOPATH/pkg/mod,所以这个路径最好保持默认($HOME/go),否则每个项目都得重新下载依赖 - 国内用户务必配代理:
go env -w GOPROXY=https://goproxy.cn,direct,否则go mod download极易卡死
最常被忽略的一点:GOROOT 和 GOPATH 的路径是否被其他工具(比如 Docker 构建脚本、systemd service 文件、IDE 的终端模拟器)真正继承。它们不认 shell 配置,得单独注入。别只在本地终端验证成功就认为万事大吉。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











