What is a utility?
A utility is a small program that does one thing well — the foundation of composable software.
- Describe what a utility program is — small, focused, does one job
- Explain why small tools are more powerful than large ones (composability, testability, reuse)
- Give examples of real utilities and what each one does
A utility is a program with a narrow, clearly defined job. It does that one
thing reliably, and it does nothing else. grep searches text for a pattern.
wc counts lines, words, and characters. sort sorts lines alphabetically.
Each is trivially simple on its own — but together they can answer almost any
question about text data.
This narrowness is not a limitation. It is the design.
The Unix philosophy
In the 1970s, the Unix operating system was built around a simple principle: write programs that do one thing and do it well, and write programs that work together. That principle — now called the Unix philosophy — turns out to be one of the most durable ideas in software.
The reasoning is straightforward. A program that does one thing:
- Is small enough to understand completely. You can read its source in an afternoon.
- Is easy to test. You can feed it known input and check the output.
- Composes cleanly. Because its input and output are predictable, you can connect it to other programs.
- Can be reused everywhere. A tool that counts lines works whether you're analyzing logs, code, or a novel.
A program that tries to do everything is the opposite on every count: hard to understand, hard to test, fragile, and impossible to reuse in unexpected contexts.
Real examples
These utilities ship with every Unix-like system. You have probably used some of them without thinking about how they were designed:
| Program | What it does |
|---|---|
cat | Reads one or more files and prints them to the terminal |
grep | Filters lines that match a pattern |
wc | Counts lines, words, and bytes in its input |
sort | Sorts lines of text |
head | Prints the first N lines |
tail | Prints the last N lines |
cut | Extracts specific columns from each line |
tr | Translates or deletes characters |
Notice that none of them know about each other. grep does not know that wc
exists. sort does not know about cat. Yet you can connect any of them in
any order through a pipe, because they all speak the same language: lines of text in, lines of
text out.
One job, done completely
"One job" does not mean "one line of code." A good utility is complete: it handles bad input gracefully, it reports errors clearly, and it exits with a status code that lets the caller know whether it succeeded. A word-counter that silently returns zero on a corrupt file is worse than useless in a pipeline — it lies to everything downstream.
The bar for a good utility is: given any valid input, produce the correct output; given any invalid input, fail loudly and clearly.
The utilities in this module are written in Python, but the ideas apply to any language. The patterns you learn here — stdin/stdout, exit codes, argument parsing — are the same whether you are writing Python, Go, or Bash.
Where to go next
Next: input and output — how Python programs read from stdin and write to stdout and stderr, and why keeping those streams separate matters.