Skip to content
C.W.K.
Stream
Lesson 06 of 10 · published

The Unix Philosophy

~10 min · philosophy, composition, history

Level 0Window Tourist
0 XP0/95 lessons0/14 achievements
0/100 XP to next level100 XP to go0% complete

Four rules from 1978

Doug McIlroy summarized Unix design in four lines that still hold:

  1. Make each program do one thing well.
  2. Expect the output of every program to become the input to another, as yet unknown, program.
  3. Design and build software, even operating systems, to be tried early, ideally within weeks.
  4. Use tools in preference to unskilled help to lighten a programming task, even if you have to detour to build the tools and expect to throw some of them out after you've finished using them.

Why this still matters

Modern equivalents of these rules: microservices (1), JSON pipelines (2), MVPs and continuous deployment (3), build scripts and CI tooling (4). Every dev practice you do today is descended from these four bullet points.

Concrete habits

  • Plain text everywhere. Logs, configs, data — text first, binary only when forced. Text travels through pipes; binary doesn't.
  • One command, one job. If your shell function is 300 lines long, you've built a tool that doesn't compose. Split it.
  • Output is contract. Programs that print stable, well-formed output (header, columns, fixed delimiters) are pipeable. Pretty-printing for humans goes through a separate flag.
  • Errors to stderr, data to stdout. Always.

The exception: jq + structured data

The line-oriented pipe model breaks for nested JSON. Modern Unix accepts this — jq, yq, and dasel are first-class citizens now, exactly because they let JSON streams compose. The philosophy didn't change, the data shape did.

A small tool should have a small responsibility

Clear inputs and outputs make stages replaceable and testable, but every new process and parsing boundary also costs something. Split work into units whose data and failures you can explain, not into the largest possible number of commands.

Verify the text-stream assumption

Classic pipelines suit line-oriented text. JSON, binary data, and filenames containing NUL or newlines need other record boundaries. Converting everything to spaces and lines can discard information.

Code

Composition over monolith·bash
# Bad — invent a new tool
# (would need a custom Python script)
# Good — compose existing tools
git log --pretty=format:'%an' \
  | sort | uniq -c | sort -rn | head

External links

Exercise

Pick a problem you'd normally solve with a 50-line Python script. Try to write a one-line shell pipeline instead. Example: count distinct authors in a git repo, sort by frequency. If you can do it, you've felt the Unix philosophy.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.