Home / Alt manpages / go-env(1)

  • go-env(1)
  • User command
  • linux

Inspect and Persist Go Settings with go env

go env is how you find out what your Go toolchain actually thinks GOPATH, GOOS or GOPROXY are, rather than guessing from a half-remembered export. This guide covers inspecting the effective environment, extracting single values for scripts, and setting a user-level default you can undo cleanly. The examples use the Debian package's /usr/bin/go, version go1.22.2 linux/amd64, installed by golang-go.

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 just checked:

$ /usr/bin/go env | sed -n '1,8p'
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/alice/.cache/go-build'
GOENV='/home/alice/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''

The full output runs longer, showing defaults and effective values together, including paths such as GOPATH, GOROOT, GOMODCACHE and GOPROXY. Empty values are meaningful: they often mean Go is using a built-in default rather than that a setting is broken.

Do not source this output blindly. It looks like shell syntax, but a diagnostic dump can include paths or settings you did not expect. If you only need one value, query it directly instead.

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/alice/go
/home/alice/.config/go/env

This is safer for scripts than parsing the complete shell-style report. A small pre-flight check, for example, 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 something to execute.

4. Ask for JSON when another tool consumes 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 values that 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, and it does not need sudo.

Warning

The next example changes how later module-aware commands behave until you undo it. Use it only once 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. A process environment variable can still take precedence over a stored default, so inspect the effective value in the same shell where the build will actually 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 here 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 only change the export in your shell startup file if you actually meant to.

Recovery

There is no rollback for a value you never recorded. 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 version reports a different release from /usr/bin/go version. Fix the PATH or use an explicit command path.
  • Confusing defaults with exports. go env -w changes 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 instead of matching against an incidental line order.
  • Accidental persistence. -w and -u change a file under your user configuration directory; they are not read-only diagnostics.

Done means

  • Binary verified: you confirmed the exact Go binary and version in use.
  • Queries work: you can query GOOS, GOARCH, GOPATH or another named setting.
  • Output format understood: you know when to use shell output and when to use -json.
  • Nothing left behind: any test setting written with -w has been checked and removed with -u, or its intended value is documented.