Linux CLI Basics
10 examples to get you started with Linux CLI for Go engineers - 7 basic and 3 intermediate.
Prerequisites
- A Linux shell (native Linux, WSL2, or macOS Terminal for most examples).
- Go 1.26.x or later installed and on your
PATH(go version). - A sample module:
mkdir goshell && cd goshell && go mod init example.com/goshell. - Optional:
sudoaccess if you try thejournalctlexample on a systemd host.
Basic Examples
1. Find Your Module Root
pwd prints the working directory; combine with ls to confirm go.mod is present.
pwd
ls -la go.mod- Run commands from the module root so
go test ./...resolves packages correctly. ls -lashows hidden files like.envthat tools such as direnv may load.- Tab completion on directory names reduces typos in long monorepo paths.
Related: Go Toolchain on Linux: Install & Version Switching - PATH and toolchain layout
2. List Packages and Binaries
tree (or find) shows layout before you run broad tests.
# install tree if missing: sudo apt install tree
tree -L 2 -I vendor
go build -o bin/api ./cmd/api 2>/dev/null || echo "adjust ./cmd/api to your layout"
ls -lh bin/-L 2limits depth so huge repos stay readable.-I vendorskips vendored trees during quick orientation.go build -oplaces artifacts in a predictablebin/directory for systemd or docker COPY.
Related: Build, Test & Profile from the Shell - build and test loops
3. Locate a Symbol with ripgrep
Search Go source faster than recursive grep.
# install: sudo apt install ripgrep # or brew install ripgrep
rg -n "func main" --glob '*.go'
rg -n "ListenAndServe" cmd/ internal/-nprints line numbers for quick editor jumps.--glob '*.go'ignores markdown and YAML noise.- ripgrep respects
.gitignoreby default, skippingvendor/when ignored.
Related: Search, ripgrep & jq for Debugging - advanced search patterns
4. Tail Application Logs
Follow logs in real time while you exercise an endpoint.
# app writing to a file
touch app.log
tail -f app.log
# another terminal: curl -s localhost:8080/healthz >> app.logtail -fblocks until new lines arrive - ideal while reproducing a bug.- Prefer structured JSON logs so a later
jqpass can filter by level. - Rotate large files with
logrotateor volume limits in containers.
Related: Search, ripgrep & jq for Debugging - jq on JSON logs
5. Inspect a Running Go Process
Find the PID and which port it holds.
pgrep -a api # replace 'api' with your binary name
PID=$(pgrep -n api)
ps -p "$PID" -o pid,cmd,%cpu,%mem,etime
ss -ltnp | grep "$PID" # or: lsof -Pan -p "$PID" -ipgrep -ashows the command line - confirms you attached to the right binary.ss -ltnpmaps sockets to PIDs on modern Linux (netstatis legacy).- Match the binary name you set with
go build -o api.
Related: systemd & Service Unit Files for Go Binaries - supervised processes
6. Send Graceful and Forceful Signals
Practice SIGTERM before reaching for kill -9.
PID=$(pgrep -n api)
kill -TERM "$PID" # same signal systemd stop uses first
sleep 2
kill -0 "$PID" 2>/dev/null && echo "still running" || echo "exited"
# last resort only:
# kill -KILL "$PID"- Go servers should trap
SIGTERMand callhttp.Server.Shutdown. kill -0checks existence without sending a signal.SIGKILLcannot be caught - use only when graceful shutdown hangs.
Related: Linux CLI Skills for Go Engineers - signals and operations
7. Export Build Environment Variables
Cross-compile from the shell without editing code.
export GOOS=linux GOARCH=amd64 CGO_ENABLED=0
go build -o dist/api-linux-amd64 ./cmd/api
file dist/api-linux-amd64
unset GOOS GOARCHCGO_ENABLED=0produces a static binary friendly to minimal container images.fileconfirms ELF vs Mach-O so you do not ship the wrong artifact.- Reset variables after the build so local
go testuses your native platform.
Related: Go Toolchain on Linux: Install & Version Switching - GOTOOLCHAIN and versions
Intermediate Examples
8. Read systemd Journal for a Service
Correlate service restarts with kernel or OOM messages.
sudo systemctl status api.service
sudo journalctl -u api.service -n 100 --no-pager
sudo journalctl -u api.service -f-ufilters by unit name - match your.servicefile.-n 100limits initial output before follow mode.- Journal timestamps help line up Go panic stack traces with deploy events.
Related: systemd & Service Unit Files for Go Binaries - unit files
9. Filter JSON Logs with jq
Count error-level lines and sample one stack trace field.
cat app.json.log | jq -c 'select(.level=="ERROR")' | head
cat app.json.log | jq -s 'map(select(.level=="ERROR")) | length'-cprints one compact JSON object per line for further piping.-sslurps the file into an array for aggregates (fine for modest files).- For huge logs, use
rg '"level":"ERROR"'first, then jq on the subset.
Related: Search, ripgrep & jq for Debugging - jq recipes
10. Pipe Test Output to a File and Search Failures
Capture CI-like output locally, then ripgrep failures.
go test ./... -count=1 2>&1 | tee test.out
rg -n "FAIL:|panic:" test.out
rg -n "--- FAIL:" test.out -A 32>&1merges stderr into stdout so panics are not lost.-count=1disables test cache when you need a fresh signal.teekeeps a file for bug reports while you watch the terminal.
Related: Build, Test & Profile from the Shell - test and profile loops
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).