Inspect and Safely Persist Go Settings with go env
You will finish with a reliable way to inspect the Go toolchain's effective environment, extract values for scripts, and set a user-level default you can undo. The examples use the Debian package's /usr/bin/go, version go1.22.2 linux/amd64, installed by golang-go.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a shell and the Go compiler package. The inspection commands are ordinary user commands. One later step writes your Go environment file, so read the warning before running it. Nothing here needs elevated privileges.
Checkpoint
The command in this guide is /usr/bin/go. Your interactive go may resolve to another installation, another version, or a wrapper. Confirm the binary before trusting its output.
1. Confirm the command and version
Start by checking the executable that will answer your queries:
$ command -v /usr/bin/go
/usr/bin/go
$ /usr/bin/go version
go version go1.22.2 linux/amd64
If you deliberately want the first go on your PATH, run command -v go and go version instead. Do not mix output from two installations when diagnosing a build. Go's supported variables and flags can differ between releases; this guide follows the installed 1.22 command and its local go-env(1) manual.
2. Print the complete environment
With no variable names, go env prints the effective environment as shell assignments. Use the package binary so the result is tied to the version you checked:
$ /usr/bin/go env | sed -n '1,8p'
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/andy/.cache/go-build'
GOENV='/home/andy/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
The full output is longer. It shows defaults and effective values together, including paths such as GOPATH, GOROOT, GOMODCACHE and GOPROXY. Empty values are meaningful: they often mean that Go is using a built-in default rather than that a setting is broken.
Do not source this output blindly. It is intended to look like shell syntax, but a diagnostic dump can include paths or settings you did not expect. If you need one value, query it directly.
3. Query selected values for a check or script
Pass one or more variable names after the command. Go prints one value per line, in argument order:
$ /usr/bin/go env GOOS GOARCH GOPATH GOENV
linux
amd64
/home/andy/go
/home/andy/.config/go/env
This is safer for scripts than parsing the complete shell-style report. For example, a small pre-flight check can compare the target operating system and architecture without trying to interpret unrelated settings:
go_bin=/usr/bin/go
target_os=$("$go_bin" env GOOS)
target_arch=$("$go_bin" env GOARCH)
printf 'Go target: %s/%s\n' "$target_os" "$target_arch"
Keep the command path quoted in real scripts if it comes from a variable. The output is data, not a command to execute.
4. Ask for JSON when another tool will consume the result
Use -json when a program needs named fields rather than shell assignments. With explicit variable names, the result contains only those fields:
$ /usr/bin/go env -json GOOS GOARCH
{
"GOARCH": "amd64",
"GOOS": "linux"
}
JSON object order is not a useful contract. Read fields by name, and expect the values to reflect the machine and the selected Go installation. A missing or misspelt variable is an error, so keep variable names copied from go env or go help environment.
5. Set a persistent default, only when you mean to
go env -w NAME=VALUE changes the default setting recorded in the file reported by go env GOENV. It is a persistent user-level change, not a temporary assignment for one command. It does not require sudo.
Warning
The next example changes how later module-aware commands behave until you undo it. Use it only if you understand the effect of GOFLAGS=-mod=readonly: commands will refuse to update go.mod automatically when dependencies need changes.
$ /usr/bin/go env -w GOFLAGS=-mod=readonly
$ /usr/bin/go env GOFLAGS
-mod=readonly
Check the value immediately after writing it. The file itself is an implementation detail; go env GOFLAGS is the useful verification command. Existing process environment variables can still take precedence over a stored default, so inspect the command's effective value in the same shell where the build will run.
6. Undo a setting written with -w
Use -u with the variable name to remove the stored default:
$ /usr/bin/go env -u GOFLAGS
$ /usr/bin/go env GOFLAGS
The final line is empty on this machine because the stored setting has been removed and no shell-level GOFLAGS is present. If your shell exports GOFLAGS, go env GOFLAGS will still show that effective value. In that case, inspect it with printf '%s\n' "${GOFLAGS-}" and remove or change the export in the shell startup file only if you intended to alter it.
There is no rollback for a value you did not record. Before using -w, save the current result of go env NAME; then restore it with another go env -w NAME=VALUE, or remove it with -u if it was previously unset.
Common traps
- Wrong binary:
go versionreports a different release from/usr/bin/go version. Fix thePATHor use an explicit command path. - Confusing defaults with exports:
go env -wchanges Go's stored defaults. It does not add an ordinary shell variable to the current shell. - Reading the whole report in a script: query named values or request JSON. Do not use text matching against an incidental line order.
- Accidental persistence:
-wand-uchange a file under your user configuration directory. They are not read-only diagnostics.
Done means
- You verified the exact Go binary and version.
- You can query
GOOS,GOARCH,GOPATHor another named setting. - You know when to use shell output and when to use
-json. - Any test setting written with
-whas been checked and removed with-u, or its intended value is documented.