For command-line tools that consume one logical stream of records, follow the behaviour associated with Perl's diamond operator <>, even when implementing the tool in another language.
Default interface
- With no positional filenames, read standard input.
- With one or more filenames, read them in argument order as one logical input stream.
- Treat a positional - as standard input at that point in the sequence.
- Write the primary result to standard output and diagnostics to standard error.
- Do not require the caller to create a temporary input file when a pipeline is sufficient.
producer | analyser
analyser input.txt
analyser first.txt second.txt
producer | analyser first.txt - last.txt
Why
- The same program composes naturally in pipelines and also works with retained evidence files.
- It is easy to test with redirection, fixtures and generated input.
- Callers can choose streaming or persistence without requiring separate program modes.
- The convention is familiar across Unix-like environments and reduces CLI-specific explanation.
Implementation guidance
- Keep input parsing independent from business logic; expose an iterator, filehandle sequence or equivalent stream abstraction.
- Do not close the process's standard input when handling -; close only filehandles the program opened itself.
- Accept repeated - only if rereading standard input has meaningful semantics; after EOF, later occurrences naturally yield no more data.
- Preserve record boundaries and input order unless the tool explicitly documents aggregation or sorting.
- Make --help show both the pipeline and filename forms.
When not to force this pattern
Use a different explicit interface when inputs have distinct roles, require random access, must be correlated rather than concatenated, or are unsafe to accept from an unbounded stream. Even then, support - for a single stream-valued input where it remains unambiguous and safe.