Terminal Tool Guides
Guides to command-line tools: step-by-step how-tos, modern replacements for Unix commands, alternatives, best-of lists and comparisons.
How-to
20A terminal git workflow with lazygit and delta
Install lazygit and delta, set delta as git's pager, render lazygit diffs with it, and stage hunks, commit and rebase from the keyboard.
Back up a directory with restic
Back up a directory to a local disk or S3-compatible storage with restic: init a repo, exclude files, restore, prune old snapshots and schedule runs.
Benchmark shell commands with hyperfine
Time shell commands with hyperfine: warmup runs, cache-clearing with --prepare, side-by-side comparisons, parameter scans and Markdown or JSON export.
Change YAML configuration with yq
Read and update a nested YAML value with mikefarah/yq, preview the result, then write it to a disposable file.
Encrypt files with age
Encrypt files with age: generate a key, encrypt to one or more recipients or SSH keys, use a passphrase, and encrypt whole directories through tar.
Filter JSON logs and count errors with jq
Use jq to select errors from JSON Lines logs, keep useful fields, and count failures by service.
Find leaked secrets in a git repo with gitleaks
Scan git history and working files for API keys and tokens with gitleaks, allowlist false positives, add a pre-commit hook and run it in CI.
Find out why it works locally but fails in CI
Snapshot your machine and your CI runner with envdiff, diff runtimes and env vars side by side, and add a check so the same mismatch can't come back.
Jump between directories with zoxide
Install zoxide, load it in bash, zsh or fish, jump with z and zi, import your autojump or z history, and replace cd with --cmd cd.
Keep work running with tmux sessions
Create, detach and reattach named tmux sessions, split windows and panes, write a minimal ~/.tmux.conf, and keep jobs alive when SSH drops.
Lint and test a shell script with ShellCheck and Bats
Catch a quoting bug with ShellCheck, then add Bats tests for names containing spaces and wildcard characters.
Manage Node, Python and Go versions per project with mise
Pin Node, Python and Go versions per project with mise: install, shell activation, mise use, mise.toml vs .tool-versions, and moving off asdf or nvm.
Navigate a Kubernetes cluster with k9s
Browse pods, deployments and services with k9s: switch contexts, filter views, read logs, open a shell, port-forward, and run it read-only.
Put repeatable project commands in a Justfile
Create a Justfile with a parameterized greeting and a test recipe, then run it from a project subdirectory.
Rerun a test when files change with Watchexec
Watch a small project with Watchexec, trigger passing and failing runs, and ignore generated files.
Search your shell history with fzf
Replace the default Ctrl-R with a fuzzy history search in bash, zsh or fish using fzf's shell integration.
Set up a fast cross-shell prompt with starship
Install starship, load it in bash, zsh or fish, edit starship.toml, apply a preset, and fix slow prompts or missing Nerd Font glyphs.
Swap ls, cat, find and grep for eza, bat, fd and ripgrep
Install eza, bat, fd and ripgrep, learn the side-by-side commands and flag differences, and alias them without breaking your scripts.
Sync and search shell history across machines with atuin
Install atuin, import your existing shell history, search it with Ctrl-R and sync it end-to-end encrypted between machines.
Write a local API smoke test with Hurl
Use a localhost JSON fixture to write a passing Hurl assertion, then verify that an incorrect expectation fails.