Post Image
microsoftMar 30, 2026

Command-Line Tools That Make Everyday Development Easier

Ruchi Yadav
Ruchi Yadav6 min read

A surprising amount of development time goes into finding things: a configuration file, a function name, an error message, or a command you ran yesterday. The terminal becomes more useful when those searches stop interrupting the task itself. Start with ripgrep, usually invoked as rg, for searching file contents. Running rg 'connection refused' searches the current directory recursively and reports matching lines with their filenames. Add -n when you want explicit line numbers, or use a glob such as rg 'timeout' -g '*.go' to focus on Go files. By default, ripgrep respects ignore rules and skips hidden files and binary files, which keeps ordinary repository searches manageable. Remember those defaults when an expected result is missing: a hidden configuration file or ignored directory may require explicit options. For finding filenames rather than their contents, fd provides a convenient interface. A command such as fd -e yaml lists matching YAML files without requiring a long expression. Then there is fzf, an interactive fuzzy finder that filters a list as you type. Feeding rg --files into fzf gives you a searchable file list, useful when you remember only part of a path. With shell integration configured, fzf can also make command history easier to search. These tools work well together because each handles a specific part of the task: ripgrep searches contents, fd locates paths, and fzf helps you choose from results. Start with whichever addresses your most frequent frustration, and learn its filtering options before adding elaborate shell customizations. GitHub

Once you find the relevant file or service, the next problem is usually understanding its output. For inspecting source files, bat adds syntax highlighting and line numbers, making a quick terminal read more comfortable. Running bat config.yaml can be enough to check a setting without opening another editor window. For long output, less remains useful because you can search within it, move between matches, and read at your own pace. API investigation often begins with curl, which lets you send requests independently of the application frontend. A command such as curl -i http://localhost:8080/health includes response headers alongside the body, helping distinguish an application response from a proxy or authentication problem. The -v option shows connection and protocol details when you need to investigate further. For scripts, --fail-with-body makes HTTP error responses produce a failure exit status while retaining their response body. That matters because receiving an HTTP response does not necessarily mean the request succeeded. Pair curl with jq when the response is JSON. Running jq '.' response.json formats a saved response, while jq -r '.items[].id' response.json extracts identifiers from an items array as plain text. Filters using select let you focus on records with a particular status or property. This is more reliable than searching JSON with text commands when field order and formatting vary. In a shell pipeline, also consider how failures propagate: a successful final command can hide an earlier failure unless your shell is configured to detect it. A readable result should not conceal a broken request. GitHub

Git becomes more useful when you learn a few inspection commands beyond add, commit, and push. Before preparing a commit, run git status --short to see a compact list of changed and untracked files. Then inspect git diff to review tracked changes that have not been staged. After staging, git diff --staged shows what the next commit will actually contain. The distinction matters when one file includes both a finished fix and an unrelated experiment. Use git add -p to stage selected changes interactively instead of automatically including the whole file. For a quick overview, git diff --stat summarizes the size of tracked changes, while git diff --check can catch certain whitespace problems. When investigating history, git log --oneline helps you scan recent commits, and git show followed by a commit identifier reveals its patch and metadata. These commands help answer concrete questions: what changed, what is ready to commit, and where did this behavior originate? If your repository lives on GitHub, the GitHub CLI brings related tasks into the same terminal session. After authentication, gh pr view displays pull request details, gh pr diff shows the proposed patch, and gh pr checks reports check results. For a failed workflow, gh run view with --log-failed helps retrieve failing step logs without manually navigating through the website. The benefit is especially noticeable when you are already investigating a problem locally and need one piece of information from CI. Keep commands readable enough that you can tell which repository, pull request, or run you are inspecting. git-diff Documentation

Some command-line tools improve how you organize work rather than how you inspect a single file. tmux lets you keep several terminal windows and panes within a session, which is useful when running a development server, watching logs, and executing tests together. You can detach from a session and reconnect later while its processes continue running, provided the host and tmux server remain alive. This is particularly helpful on a remote machine where a dropped SSH connection would otherwise disrupt your working session. Give sessions recognizable names so returning to a project does not begin with guessing which terminal contains the right process. Repeated project commands deserve similar attention. If starting a service requires several remembered options, put the command in an existing project script or task file and make it available to teammates. Personal aliases are convenient for short, interactive actions, but essential build and test instructions should be discoverable in the repository. Learn the help output for the tools you use regularly, including how they interpret patterns, quote arguments, and report failures. When passing filenames between commands, account for spaces and other unusual characters; null-delimited output is useful where the participating tools support it. Avoid building a complicated pipeline before checking the output of its individual stages. A small command that you understand is easier to troubleshoot than an impressive-looking sequence copied without context. You do not need every utility mentioned here. Choose one recurring task, make it easier, and keep the commands that prove useful during ordinary development.