Linux CLI Basics
10 examples to get you started with Linux CLI for Go engineers - 7 basic and 3 intermediate.
Search across all documentation pages
10 examples to get you started with Linux CLI for Go engineers - 7 basic and 3 intermediate.
PATH (go version).mkdir goshell && cd goshell && go mod init example.com/goshell.sudo access if you try the journalctl example on a systemd host.pwd prints the working directory; combine with ls to confirm go.mod is present.
pwd
ls -la go.modgo test ./... resolves packages correctly.ls -la shows hidden files like .env that tools such as direnv may load.Related: Go Toolchain on Linux: Install & Version Switching - PATH and toolchain layout
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 2 limits depth so huge repos stay readable.-I vendor skips vendored trees during quick orientation.go build -o places artifacts in a predictable bin/ directory for systemd or docker COPY.Related: Build, Test & Profile from the Shell - build and test loops
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/-n prints line numbers for quick editor jumps.--glob '*.go' ignores markdown and YAML noise..gitignore by default, skipping vendor/ when ignored.Related: Search, ripgrep & jq for Debugging - advanced search patterns
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 -f blocks until new lines arrive - ideal while reproducing a bug.jq pass can filter by level.logrotate or volume limits in containers.Related: Search, ripgrep & jq for Debugging - jq on JSON logs
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 -a shows the command line - confirms you attached to the right binary.ss -ltnp maps sockets to PIDs on modern Linux (netstat is legacy).go build -o api.Related: systemd & Service Unit Files for Go Binaries - supervised processes
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"SIGTERM and call http.Server.Shutdown.kill -0 checks existence without sending a signal.SIGKILL cannot be caught - use only when graceful shutdown hangs.Related: Linux CLI Skills for Go Engineers - signals and operations
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=0 produces a static binary friendly to minimal container images.file confirms ELF vs Mach-O so you do not ship the wrong artifact.go test uses your native platform.Related: Go Toolchain on Linux: Install & Version Switching - GOTOOLCHAIN and versions
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-u filters by unit name - match your .service file.-n 100 limits initial output before follow mode.Related: systemd & Service Unit Files for Go Binaries - unit files
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'-c prints one compact JSON object per line for further piping.-s slurps the file into an array for aggregates (fine for modest files).rg '"level":"ERROR"' first, then jq on the subset.Related: Search, ripgrep & jq for Debugging - jq recipes
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>&1 merges stderr into stdout so panics are not lost.-count=1 disables test cache when you need a fresh signal.tee keeps 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).
Reviewed by Chris St. John·Last updated Jul 18, 2026