wunder beta

📘 How do you build a solid CLI?

When you type a command and press Enter, the shell forks and executes a new process,

6
lessons
~30 min
to learn
Adults
level
Start the course →

What you’ll learn

  1. What a Command-Line App Really IsExplain the process model, standard streams, and exit-status contract that every command-line application participates in.A CLI app is an ordinary process that the shell launches with an argument vector and three open file descriptors: stdin (0), stdout (1), and stderr (2). It communicates results as text on stdout, diagnostics on stderr, and a single success/failure signal through its integer exit status. Internalizing this contract early is what lets your program cooperate with pipes, scripts, and other tools instead of fighting them. Everything later in the course is built on these primitives.
  2. Arguments, Options, and POSIX ConventionsParse and design command-line arguments that follow the POSIX Utility Syntax Guidelines so your interface matches user expectations.Users carry deep muscle memory about how options look: single-letter flags after a hyphen, the ability to bundle them, a double-hyphen to stop option processing, and operands at the end. The Open Group's Utility Syntax Guidelines codify these expectations precisely, and matching them makes your tool feel native. The distinction between options (flags that modify behavior), option-arguments (values attached to a flag), and operands (the things you act on) gives you a vocabulary for designing a clean interface. Following convention is not pedantry; it is how you avoid surprising the people and scripts that call you.
  3. Input, Output, and Exit Codes Done RightImplement disciplined stream handling and meaningful exit codes so your tool is scriptable and composable.A scriptable tool treats its streams as contracts: results on stdout, diagnostics on stderr, and graceful handling of stdin so it can sit in a pipeline. Exit codes turn your program into something other programs can reason about, with zero for success and distinct non-zero codes for distinct failures. Conventions such as supporting '-' for standard input and not decorating stdout keep your tool composable. Get these right and your small program multiplies its usefulness by combining with everything else.
  4. Configuration, Environment, and SubcommandsLayer configuration sources with clear precedence and structure larger tools using subcommands and help.Real tools draw settings from several places at once: built-in defaults, configuration files, environment variables, and command-line flags. A clear precedence order, with explicit flags overriding the environment, which overrides files, which override defaults, makes behavior predictable and debuggable. As a tool grows, subcommands organize related actions under one executable, much like 'git commit' and 'git push', and well-structured help ties the whole interface together. These patterns are how a small script matures into a maintainable application.
  5. Robustness, Testing, and PackagingMake a CLI trustworthy through input validation, automated testing of its observable contract, and distributable packaging.A trustworthy CLI validates input early and fails with clear messages, so users are guided rather than confronted with stack traces. Because a CLI's contract is observable (its stdout, stderr, and exit code for given arguments and stdin), it is highly testable end to end by running it as a subprocess and asserting on those three outputs. Packaging then turns your working script into something installable and runnable by name, with documentation and a defined entry point. Together, validation, testing, and packaging are what separate a personal script from shareable software.
  6. Guided Build: A Word-Count CLI From ScratchBuild, test, and package a small but complete command-line application that follows every convention from this course.This capstone walks you through building 'wcli', a word-count style tool that reads files or stdin, supports options, returns proper exit codes, and ships as an installable command. You will apply every prior lesson: stream discipline, POSIX-style parsing, configuration precedence, validation, testing of the observable contract, and packaging with an entry point. The artifact is deliberately small so the focus stays on doing each convention correctly rather than on feature volume. By the end you will have a tool you could genuinely install and put inside a real pipeline.

Questions this course answers

By convention, where should a CLI program send its primary results versus its error and diagnostic messages?

Primary, machine-readable output goes to stdout (fd 1) so it can be piped, while diagnostics and errors go to stderr (fd 2) so they stay visible to a human even when stdout is redirected. This separation is what keeps pipelines clean.

A shell line reads `build && deploy`. What must `build` do for `deploy` to run?

The `&&` operator runs the right-hand command only if the left-hand command exits with status 0 (success). Exit status, not printed text, is what the shell inspects, which is why setting it deliberately matters.

Why should a well-behaved CLI check whether stdout is a terminal (TTY) before adding color codes?

If stdout is a pipe or file rather than a terminal, color/formatting escape sequences become noise in the data stream that downstream tools must parse. Detecting a TTY (e.g., via isatty) lets the program emit human-friendly output only when a human is actually watching.

In the command `grep -i -n pattern file.txt`, what is `pattern`?

`-i` and `-n` are options that take no arguments here, so `pattern` and `file.txt` are operands (non-option arguments). Per Guideline 9, operands follow the options on the command line.

What does the first standalone `--` argument signify under the POSIX guidelines?

Guideline 10 states the first '--' that is not an option-argument is the delimiter ending option processing. This lets you pass operands that begin with a hyphen, such as a file literally named '-x', without them being parsed as flags.

Per the guidelines, which write of the same three argument-less flags is conventionally valid bundling?

Guideline 5 permits grouping multiple options that take no option-argument behind a single hyphen, so `-l -a -h` may be written `-lah`. The double-hyphen form `--lah` would denote a single long option, not three bundled short options.

Grounded in trusted sources

  • POSIX utility conventions / IEEE Std 1003.1 — argv and exit status norms
  • Python argparse docs — options and subcommands, https://docs.python.org/3/library/argparse.html
  • The Art of Unix Programming (Eric S. Raymond) — CLI composition habits
  • Click / Typer documentation — modern Python CLI patterns
  • GNU Coding Standards — command-line interface guidelines

Every Wunder lesson is built from real, reputable sources — never invented.

Related courses

Wunder is a personalized learn-anything platform — tell it any topic and it builds a beautiful, fact-checked course in minutes, with narration, a knowledge check, and a college-style University track.

All topics · Home

© 2026 Wunder Learning LLC · Terms & Privacy