Recent from talks
Nothing was collected or created yet.
Usage message
View on WikipediaThis article may be confusing or unclear to readers. (April 2008) |
In computer programming, a usage message or help message is a brief message displayed by a program that utilizes a command-line interface for execution. This message usually consists of the correct command line usage for the program and includes a list of the correct command-line arguments or options acceptable to said program.
Usage messages are utilized as a quick way for a program to inform the user of proper command syntax, and should not be substituted for proper error messages or for detailed documentation such as a man page.
Pattern
[edit]On Unix-like platforms, usage messages usually follow the same common pattern:
- They often begin with "Usage:", the command, followed by a list of arguments.
- To indicate optional arguments, square brackets are commonly used, and can also be used to group parameters that must be specified together.
- To indicate required arguments, angled brackets are commonly used, following the same grouping conventions as square brackets.
- Exclusive parameters can be indicated by separating them with vertical bars within groups.
Examples
[edit]Here is an example based on the NetBSD source code style guide:
Usage: program [-aDde] [-f | -g] [-n number] [-b b_arg | -c c_arg] req1 req2 [opt1 [opt2]]
This would indicate that "program" should be called with:
- options without operands: a, D, d, e (any of which may be omitted). Note that in this case some parameters are case-sensitive
- exclusive options: f, g (denoted by the vertical bar)
- options with operands: n
- exclusive options with operands: b, c
- required arguments: req1, req2
- optional argument opt1, which may be used with or without opt2 (marked optional within the group by using another set of square brackets)
- optional argument opt2, which requires opt1
Implementation
[edit]To print a usage statement in a shell script, one might write:
case "$arg" in
...
h) printf 'Usage: %s parameter1 parameter2 ...\n' "$(basename "$0")"
exit 0
;;
...
esac
Anti-patterns
[edit]A usage statement is not an error message, and thus it should generally only be printed when specifically requested by the user (via --help, or -h, or -?, or some similar flag or argument). It should be written to the standard error;[1][2] if the user has entered an incorrect command, the program should ideally respond with a succinct error message that describes the exact error made by the user rather than printing the usage statement and requiring the user to figure out what the mistake was. If the user fails to pass the correct number of arguments, for example, a single line stating that an argument is missing is far more useful than several pages of output providing a general usage.
See also
[edit]References
[edit]Usage message
View on Grokipedia-h or --help.[1][2][3]
These messages serve as an immediate aid for users, promoting usability by adhering to established conventions that ensure portability across POSIX-compliant systems, conventionally output to standard error (stderr) for cases involving errors or invalid input, to distinguish them from normal program output on standard output (stdout), although explicit help requests like --help are often directed to stdout per guidelines such as GNU standards.[3][4][5] The format draws from the SYNOPSIS section of manual pages, starting with "usage:" followed by the program name and a stylized representation of arguments, using square brackets [] for optional elements, ellipses ... for repetitions, and vertical bars | for alternatives.[2][3]
Originating from early Unix utilities, usage messages have evolved as a core element of CLI design, with modern guidelines emphasizing clarity, such as leading with examples, suggesting corrections for errors, and linking to fuller documentation, while avoiding terminal-specific formatting to maintain compatibility.[1][4] In POSIX standards, they support argument parsing rules where options are single alphanumeric characters preceded by a hyphen, options precede operands, and the double hyphen -- terminates option processing.[3]
Fundamentals
Definition and Purpose
A usage message is a standardized textual output produced by software applications, particularly command-line programs, that outlines the proper syntax, available options, and required arguments for correct invocation. It is typically displayed when the program is called with invalid parameters, missing inputs, or a dedicated help flag such as-h or --help. In this context, syntax refers to the structural rules governing how the command must be formatted on the command line, while options are modifiable flags (e.g., -v for verbose mode) and arguments are positional inputs like file paths or values that the program processes. This output serves as an immediate, built-in reference, distinguishing it from fuller documentation like manual pages.[6][7][8]
The primary purpose of a usage message is to enhance usability by delivering concise, on-demand guidance that helps users quickly correct errors and learn the interface without consulting external resources. By embedding this self-documentation directly into the program, it reduces reliance on support teams or separate help files, thereby streamlining workflows in technical environments. Furthermore, it promotes accessibility for novice users who may lack deep familiarity with command-line interfaces, offering a low-friction entry point to functionality that might otherwise seem opaque. This approach aligns with broader principles of user-centered design in software, where immediate feedback minimizes frustration and encourages productive interaction.[1][2][9]
Usage messages represent an evolution from rudimentary error reporting in early computing systems, shifting from mere reactive notifications of failure—often terse and unhelpful scoldings—to proactive aids that educate and empower users. This transition emphasized constructive communication over punishment, fostering a more forgiving interaction model. Such features first appeared in the command-line tools of early Unix shells during the 1970s, as part of the operating system's foundational emphasis on simplicity and programmer efficiency.[10][11][12]
Historical Context
The concept of usage messages originated in the early 1970s amid the development of Unix at Bell Labs. The inaugural edition of the Unix Programmer's Manual, released on November 3, 1971, documented 61 commands using terse, roff-formatted pages designed for quick reference, marking an early effort to provide accessible help without excessive verbosity. By 1972, theman command formalized this system, allowing users to retrieve on-demand documentation, while the Bourne shell, introduced in 1977, exemplified Unix's adherence to the principle of least surprise in command-line interface (CLI) design, which emphasizes predictable behaviors including informative error handling and option feedback.[13][14][15]
This evolution contrasted sharply with the opaque error reporting of 1960s mainframe systems, such as IBM's OS/360, where diagnostics relied on cryptic codes like S0C7 (indicating a data exception) or S0C1 (an operation exception), often requiring extensive core dumps for resolution and frustrating users with minimal contextual guidance. Unix's man pages and nascent usage outputs addressed this by prioritizing clarity and brevity, enabling developers to integrate succinct help summaries directly into tools, thus reducing reliance on lengthy external references.
A pivotal milestone came with the POSIX.1 standard in 1988, which standardized the getopt utility for parsing command-line arguments and provided guidelines for diagnostic messages on invalid options, promoting the convention of including usage summaries for enhanced usability. During the 1980s, Microsoft adopted analogous practices in MS-DOS (introduced in 1981) and the Windows Command Prompt, where the /? switch displayed command syntax and options, facilitating cross-platform familiarity.[16][17]
The 1990s open-source movement, catalyzed by the Linux kernel's 1991 release and the formation of the Open Source Initiative in 1998, drove a cultural shift toward greater end-user accessibility in CLI tools, including the widespread adoption of help mechanisms like -h to broaden usage beyond experts. This momentum extended into the 2000s with web and containerization tools, such as Git (2005) for version control and later npm (2010) and Docker (2013), which embedded comprehensive usage messages to support diverse developer workflows.[18]
Design and Structure
Standard Patterns
Standard usage messages typically follow a basic template that begins with a synopsis line providing a quick reference for the command's syntax, such as "usage: command [options] [arguments]", followed by detailed descriptions of each element.[3] This format ensures users can rapidly identify required and optional components without parsing extensive documentation. The synopsis line uses conventions like square brackets [ ] to denote optional elements, such as [options] or [file], and ellipses ... to indicate repeatable arguments, for example, [operand...].[3] Variations in usage message paradigms include short forms for immediate error feedback, which display minimal syntax upon detecting issues like invalid arguments, contrasted with long forms triggered by an explicit --help flag that provide comprehensive details including examples and explanations.[19] Although --help is not mandated by POSIX, it has become a de facto standard in many Unix-like systems for accessing extended usage information.[3] Additionally, these messages often incorporate standardized exit codes to signal errors; for instance, a usage error typically returns code 64 (EX_USAGE) as defined in sysexits.h, indicating incorrect command invocation such as wrong argument count or bad syntax.[20] Standardization efforts for usage messages are rooted in IEEE POSIX standards, particularly the utility conventions outlined in POSIX.1, which specify argument syntax notation to promote portability across systems.[3] Earlier influences include the X/Open Portability Guide version 4 (XPG4) from 1992, which aligned with POSIX.2 (IEEE Std 1003.2) to define consistent patterns for options prefixed with a hyphen (-) and operand handling.[21] These conventions emphasize alphabetical listing of options where possible and clear delineation of mutually exclusive choices, often shown on separate synopsis lines, to enhance readability and interoperability.[3] The flow logic for displaying usage messages is conventionally triggered by conditions such as invalid input, unknown flags, or the explicit invocation of a help option like --help, at which point the message is output to standard error before exiting.[3] This can be achieved through automatic generation via argument parsers that validate input against predefined rules or manual crafting in the program's error-handling code, balancing brevity with informativeness.[19]Key Components
A usage message's core elements form its foundational structure, enabling users to quickly grasp how to invoke a command. The command name appears prominently at the outset, identifying the program and often followed by a synopsis of its syntax. Options are denoted by short forms using a single hyphen (e.g., -f) for brevity and long forms with double hyphens (e.g., --file) for readability, allowing users to customize behavior such as input sources or output formats. Arguments include positional ones, where sequence determines function (e.g., source followed by destination), and named ones associated with options, distinguishing essential inputs from configurable parameters. These components collectively promote clarity by delineating required actions from elective modifications.[19][4] Descriptive text accompanies these elements to provide concise explanations, enhancing usability without overwhelming the user. Each option and argument receives a brief description of its purpose, such as specifying a file path or verbosity level, ensuring users understand implications like data processing or error handling. Notation conventions clarify requirements: angle bracketsPractical Examples
Command-Line Tools
In Unix-like operating systems, thels command exemplifies a simple usage message designed for quick reference in file listing tasks. When invoked without arguments or with the --help flag, it displays: Usage: ls [OPTION]... [FILE]... followed by a concise list of options such as -l for long format and -a for all files including hidden ones.[24] This structure prioritizes essential syntax while directing users to the full manual for details, ensuring minimal disruption in terminal workflows.
The grep command, used for pattern searching in text, provides a similarly structured message: Usage: grep [OPTION]... [PATTERN](/page/Pattern) [FILE]... upon running grep --help. It includes examples of options like -i for case-insensitive matching and -r for recursive search, often spanning multiple lines to cover common flags without overwhelming the user.[25] This output balances brevity with actionable details, allowing rapid correction of input errors like missing patterns.
On Windows, the dir command, analogous to ls, outputs a usage summary via dir /?: dir [<drive>:][<path>][<filename>] [...] [/p] [/q] [/w] [/d] [/a[[:]<attributes>]] [/o[[:]<sortorder>]] [/t[[:]<timefield>]] [/s] [/b] [/l] [/n] [/x] [/c] [/4] [/r]. This lists core switches for display formats, sorting, and attributes, emphasizing path and file specifications first.[26] For more complex scenarios, robocopy—a robust file copying tool—shows via robocopy /?: Usage: robocopy <source> <destination> [<file>[...]] [<options>], detailing over 80 switches like /e for empty subdirectories and /log:<file> for output logging, grouped by category for navigability.[27] These messages handle intricate argument requirements by categorizing options, aiding users in mirroring directory structures accurately.
Cross-platform tools like curl, for data transfers, adapt usage messages to context; running curl without a URL triggers: Usage: curl [options...] <url>, with --help expanding to a categorized list of over 200 options, such as -X for HTTP methods and -o for output files.[28] In error cases like a missing URL, it reiterates the core syntax and suggests common fixes, preventing ambiguity in network diagnostics.
These examples from high-use CLI tools highlight usage messages' emphasis on brevity—limiting to 1-2 lines of core syntax—while ensuring actionability through option summaries and error-specific prompts, facilitating efficient command correction in resource-constrained environments.[24][25][26][27][28]
Scripting Languages
In scripting languages, usage messages are often dynamically generated to provide users with clear instructions on script invocation, arguments, and options, enhancing usability in custom automation tasks. These messages are typically printed to standard error or help output when invalid inputs are detected or when a help flag is invoked, allowing scripts to self-document their interfaces without relying on external manuals. Unlike static messages in pre-built tools, scripting environments emphasize flexibility, enabling developers to tailor output based on script logic or runtime conditions. In Bash and Zsh shells, usage messages are commonly implemented using simple echo statements combined with the$0 variable to reference the script name, such as echo "usage: $0 [options] <file>" >&2 to display errors on stderr. This approach integrates seamlessly with the built-in getopts command for parsing options, where invalid arguments trigger a custom message like echo "usage: $0 [-a] [-b value] file" >&2; exit 1, ensuring the script exits gracefully while informing the user of expected syntax. The getopts utility processes short options (e.g., -a or -b) and can be looped to handle multiple flags, with the usage message serving as the first line of defense against misuse in shell scripts.
Python's argparse module automates usage message generation, producing formatted output like usage: script.py [-h] arg when the -h flag is used or errors occur, including details on required positional arguments and optional flags. Developers define arguments via parser.add_argument(), and the module handles help text, type checking, and error reporting, such as displaying usage: script.py [-h] {subcommand} ... for subparsers in complex scripts. This built-in functionality reduces boilerplate, allowing focus on logic while ensuring messages reflect the parser's configuration, as seen in standard library examples where parser.print_help() explicitly outputs the full usage synopsis.
For JavaScript in Node.js environments, the Commander.js library facilitates usage messages in the style of npm commands, generating output like usage: node app.js [options] <command> upon invalid input or help invocation. It supports defining options with program.option('-p, --port <number>', 'port number') and subcommands via program.command('start'), emphasizing hierarchical structures common in package managers, where the message dynamically lists available subcommands and their descriptions. This library's parser throws errors that trigger the usage display, promoting consistent CLI interfaces in server-side scripts or tools.
Scripting usage messages often adapt to runtime variability, such as conditionally including options based on script state—for instance, in Bash, checking if a file exists before adding a -d flag to the usage echo, or in Python using argparse conditional groups to alter the printed synopsis if environment variables indicate a debug mode. These adaptations ensure messages remain relevant without overcomplicating the interface, aligning with standard CLI patterns for error handling.
Implementation Approaches
Core Techniques
Core techniques for generating and displaying usage messages in command-line tools revolve around detecting invocation errors, constructing informative text, directing output appropriately, and integrating with error contexts to guide users toward correction. Parsing triggers initiate the display of a usage message when the command receives invalid or insufficient input. This detection commonly occurs through simple argument counting, where the program verifies if the required number of positional arguments (e.g., via argc in C or equivalent in other languages) matches expectations, or via flag validation that checks for recognized options and their associated values. Upon identification of such issues, the program terminates execution with a non-zero exit code, typically 1 for general errors or 2 for misuse, as per POSIX recommendations for utilities. Historical libraries like getopt facilitate this by returning a special character ('?') on parsing errors, prompting developers to invoke the usage display.[29] Generation methods for usage messages range from manual construction using string templating to automated approaches via parsing libraries. In manual templating, developers format the message with placeholders for options and arguments, often employing functions like printf in C to insert dynamic elements such as the program name or specific invalid flags. Automated generation leverages libraries that introspect command definitions to produce structured output, including synopses like "program [-o file] [input]", without requiring hardcoded strings.[30] These methods ensure the message adheres to conventions such as listing options before operands and using brackets [] for optional elements.[31] Output handling directs the usage message to the appropriate stream for visibility and piping compatibility. Error-triggered usage prints to standard error (stderr) to distinguish them from normal output, allowing users to redirect successful results to files without including diagnostic text; in contrast, explicit help requests (e.g., via --help) may route to standard output (stdout) for similar reasons. For enhanced readability, especially in terminals, formatting techniques like ANSI escape sequences apply colors (e.g., red for errors) or bold text, though these must be terminal-aware to avoid corrupting piped output. Error integration ties the usage message directly to the failure context, providing targeted guidance rather than generic text. For instance, a message might specify "missing required argument for -f option" followed by the full usage synopsis, enabling users to identify and fix the precise issue, such as supplying a filename. This approach aligns with POSIX diagnostics, which emphasize clear indication of out-of-range or invalid inputs, and extends to suggestions like recommending default values or common fixes when applicable.[30]Language-Specific Methods
In C and C++, usage messages are typically constructed manually using standard I/O functions likefprintf to output to stderr, often in conjunction with the getopt.h library for option parsing. The getopt function processes command-line arguments but does not automatically generate help text; developers must explicitly print usage information upon parsing errors or invalid inputs. For instance, a common pattern involves checking the optopt variable for unrecognized options and printing a formatted message, such as:
fprintf(stderr, "Usage: %s [options]\n", argv[0]);
fprintf(stderr, "Usage: %s [options]\n", argv[0]);
argparse module for command-line parsing, where usage messages are generated automatically via the ArgumentParser.print_help() method. This method outputs a comprehensive help message to a specified file (defaulting to sys.stdout), including the program's usage synopsis, argument descriptions, and any epilog text defined during parser setup. For example:
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
args = parser.parse_args()
parser.print_help()
import argparse
parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
const=sum, default=max,
help='sum the integers (default: find the max)')
args = parser.parse_args()
parser.print_help()
optparse module, deprecated since Python 3.2 in favor of argparse, offered similar functionality but with less flexibility and no subcommand support; its use is discouraged for new code.[33][34]
In Go, the standard flag package supports basic command-line parsing with customizable usage messages through the global Usage function variable. Developers can override flag.Usage to define a tailored output routine, which is invoked on parsing errors; by default, it prints a header followed by flag.PrintDefaults() to list all flags with their descriptions. An example customization is:
package main
import (
"flag"
"fmt"
"os"
)
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
flag.PrintDefaults()
}
flag.Parse()
}
package main
import (
"flag"
"fmt"
"os"
)
func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
flag.PrintDefaults()
}
flag.Parse()
}
cobra library builds on flag to provide structured help generation, including automatic usage output for commands and subcommands when -h or --help is invoked. Cobra's Command struct includes fields like Use and Short that populate dynamic help messages, supporting nested hierarchies common in tools like Kubernetes.[35][36]
Java relies on external libraries for robust CLI handling, as the standard library lacks a dedicated parser. The Apache Commons CLI library uses a HelpFormatter class to generate and print usage messages based on an Options object, allowing specification of syntax, headers, and footers for formatted output to a PrintWriter. A typical usage involves building options and then:
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("java App", options);
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("java App", options);
@Command and @Option for declarative setup, automatically generating colorful, ANSI-styled usage messages via CommandLine.usage(). Customization occurs through attributes such as header, footer, and description, enabling dynamic help without manual string construction; for example, @Command(mixinStandardHelpOptions = true) adds built-in --help support.[37][38]
These language-specific methods differ notably in automation and effort required: Python's argparse and Java's picocli emphasize declarative, auto-formatted output with minimal boilerplate, contrasting C/C++'s manual printf-based construction that demands explicit control over every detail, while Go's flag strikes a balance via simple functional overrides but requires libraries like cobra for richer, verbose help in production CLIs.[33][32]
Best Practices and Pitfalls
Guidelines for Effective Design
Effective usage messages should prioritize clarity by employing simple, straightforward language that avoids unnecessary jargon, ensuring accessibility for users of varying expertise levels.[4][1] To maintain readability, these messages focus on essential information without overwhelming the user.[4] For complex options, incorporating brief examples illustrates practical application, such as demonstrating a command with sample inputs and expected outputs.[4] Conciseness is achieved by prioritizing a high-level synopsis that outlines core usage patterns over exhaustive lists of every possible flag or parameter.[4][1] Consistent formatting, such as using all lowercase for command names and standardized option styles (e.g.,--option for long flags), enhances uniformity and reduces cognitive load.[4]
User-centric design involves anticipating common errors, such as invalid arguments, and responding with constructive suggestions rather than cryptic failures.[4] Positive guidance, like recommending "try: command --help" for further assistance, empowers users to resolve issues independently.[1] Integrating with logging mechanisms, such as directing messages to stderr for separation from normal output, facilitates debugging while preserving clean user interactions.[4][1]
