2.6 go env: Inspecting the Go Environment
Right, so you’ve got Go installed. You ran the installer, maybe you even compiled it from source to feel like a real wizard. But how do you know it’s set up correctly? How do you see what Go itself thinks about its own world? You ask it. Politely. With the go env command.
Think of go env as your backstage pass to the Go opera. It shows you all the environmental variables and paths that the go tool is using to make decisions. This isn’t just a list of boring settings; it’s the very DNA of your current Go workspace. When something goes weird—and it will—this is your first stop for forensic evidence.
The Basic Invocation: Just the Facts, Ma’am
Running it plain is the most common and useful way. It dumps out a whole key-value list of the environment.
$ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/you/.cache/go-build'
GOENV='/home/you/.config/go/env'
GOEXE=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/you/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/you/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.21.4'
GCCGO='gccgo'
AR='ar'
CC='gcc'
CXX='g++'
... # (it goes on for a while, I've truncated it)
This looks like a lot, but you don’t need to memorize it. You just need to know how to find what you’re looking for.
Querying a Specific Variable
You don’t need to scroll through that wall of text every time. You can ask for a specific variable by name. This is incredibly handy for scripts or when you’re debugging one specific thing.
$ go env GOPATH
/home/you/go
$ go env GOROOT
/usr/local/go
$ go env GOPROXY
https://proxy.golang.org,direct
See? Instant answers. No grep required. The designers got this one right.
Why GOROOT and GOPATH Matter (And Why They Matter Less Now)
Let’s demystify the two big ones you’ll see. GOROOT is where the Go language itself—the compiler, standard library, and all the core tools—is installed. It’s the foundation. You generally shouldn’t mess with this. If it’s wrong, nothing works.
GOPATH is where your code and the third-party code you download live. It’s a workspace concept. Historically, you had to put all your projects in $GOPATH/src/github.com/yourname/yourproject, which felt a bit like being sent to your room. Thankfully, with Go Modules (enabled by default since Go 1.16), this is largely a thing of the past. You can now put your code anywhere on your disk, like a free-range program. GOPATH now primarily serves as the local download cache for modules. You can check where yours is, but you’ll rarely need to touch it directly anymore.
The GOOS and GOARCH of It All
These two variables are the secret sauce behind Go’s famed cross-compilation. GOOS is the Operating System (linux, windows, darwin for macOS) and GOARCH is the architecture (amd64, arm64, 386).
The magic trick? You can set these as environment variables before running go build to cross-compile effortlessly. Want to build a Windows executable from your cozy Linux machine? Easy.
$ env GOOS=windows GOARCH=amd64 go build -o myapp.exe .
The go env command tells you what your current values are, which is the default target for your builds. It’s the answer to the question, “What am I building for right now?”
When Things Go Sideways: The GOENV File
Notice the GOENV line in the output? That’s the location of your personal, user-specific Go environment configuration file. This is where settings you want to be permanent live. The go tool writes to this file when you use go env -w. This is a much cleaner solution than cluttering up your shell’s .bashrc or .zshrc with a dozen export commands.
For example, if you’re on a slow connection and want to avoid the default checksum database, you can persistently set it to be off. (A questionable choice for security, but sometimes a practical one).
$ go env -w GOSUMDB=off
This writes GOSUMDB=off to that GOENV file. To undo it and revert to the default, you use -u.
$ go env -u GOSUMDB
Crucial Pitfall: You cannot use go env -w to set variables that are inherently about the execution environment, like CC (your C compiler) or GOROOT. The tool isn’t stupid; it stops you from shooting yourself in the foot that badly. For those, you still use your shell’s environment.
So, use go env to see the lay of the land, to debug “but it works on my machine” problems, and to permanently set your preferences without making a mess of your shell config. It’s a small command with a huge amount of insight packed into it.