Documentation
Syntax
- Usage patterns
- Positional arguments
- Options
- Optional elements
- Required groups
- Mutually exclusive elements
- Repeatable elements
- The
[options]shortcut - Argument formatting rules
- Advanced usage patterns
Usage patterns
The keyword usage: (case-insensitive) introduces the usage patterns. A pattern on the same line
as usage: is the only pattern. To declare several patterns, put usage: on its own line and
write one indented pattern per line; the list ends at an empty line or a non-indented line. The first
word of each pattern is the program’s name. Here is a minimal example for a program that takes no
command-line arguments:
Usage: my_program
Programs can have several patterns listed with various elements used to describe the pattern:
Usage:
my_program command <argument>
my_program [<optional-argument>]
my_program (either-this-command | or-this-other-command)
my_program <repeating-argument> <repeating-argument>...
Each of the elements and constructs is described below. We will use the word word to describe a
sequence of characters delimited by either whitespace, one of []()| characters, or ....
Positional arguments
Words starting with “<”, ending with “>” or words in UPPER-CASE are interpreted as positional arguments. Any other word is a command, which must be given literally.
Usage: my_program <host> <port>
Usage: my_program HOST PORT
Both styles are equivalent, though the <argument-name> style is recommended for clarity. Positional
arguments are required by default unless placed within optional brackets [].
Names are ASCII words: a letter, then letters or digits (lowercase inside <>, uppercase for
NAME), with words joined by - or _, such as <file1> or FILE-2. When used in your program,
these positional arguments will be available as variables with their name in lowercase and -
replaced by _:
# If invoked as: my_program example.com 8080
# The variables available would be:
host = "example.com"
port = "8080"
Options
Words starting with one or two dashes (with exception of -, -- by themselves) are interpreted
as short (one-letter) or long options, respectively.
- Short options can be
stackedmeaning that-abcis equivalent to-a -b -c. - Long options can have arguments specified after space or equal
=sign:--input=ARGis equivalent to--input ARG. - Short options can have arguments specified after optional space:
-f FILEis equivalent to-fFILE.
Examples:
Usage: my_program -o
Usage: my_program --output=FILE
Usage: my_program -i INPUT
Options are described in the help text, conventionally under Options:. Every line that starts
with an option declares it: its short and/or long aliases (separated by a space or ,), an
optional value placeholder, then at least two spaces and a description. Lines starting with a
bare -, such as Markdown bullets (- note), are not option descriptions. A [default: value] in
the description sets the value used when the option is not given:
Options:
-v --verbose Enable verbose output
-o FILE, --output=FILE Write output to FILE
--port=<port> Port to listen on [default: 8080]
A single space or a tab does not separate the description: in -v --verbose Verbose output, the
word Verbose is the value placeholder, so --verbose takes a value and --verbose alone fails
with Option --verbose requires a value. [default: value] must be written in lowercase.
Aliases resolve to one option, stored under its long name (options.output, whether -o or
--output is used). An option can also appear only in a usage pattern; it then has no description
and no default.
Options are matched at the position where the pattern declares them. Adjacent optional options
([-v] [-q]) and the options in [options] can be given in any order
among themselves, but my_program [--verbose] <file> does not accept my_program file --verbose.
Long options must be spelled in full.
Note: Writing --input ARG (as opposed to --input=ARG) is ambiguous, meaning it is not
possible to tell whether ARG is option’s argument or a positional argument. In usage patterns
this will be interpreted as an option with argument only if a description (covered below) for that
option is provided. Otherwise, it will be interpreted as an option and a separate positional argument.
There is the same ambiguity with the -f FILE and -fFILE notation. In the latter case, it is not
possible to tell whether it is a number of stacked short options, or an option with an argument.
These notations will be interpreted as an option with argument only if a description for the option
is provided.
Warning: Options should be passed to rash after -- to be interpreted as script arguments.
Otherwise, they will be treated as options for rash itself:
# Correct (using --):
rash script.rh -- --option value
# Incorrect (option passed to rash, not your script):
rash script.rh command --option value
# Incorrect (option passed to rash, not your script):
rash script.rh --option value
Note: The shebang line #!/usr/bin/env -S rash -- passes every argument to the script, so
./script.rh --option value works.
The -- separator and -
A -- in the arguments ends the options: every later argument is a positional value, even if it
starts with -. A lone - and -- in a usage pattern are commands, stored as _ and __;
declare [--] to record whether -- was given:
Usage: my_program [options] [--] <file>...
# my_program -v -- -x.txt -> options.verbose = true, __ = true, file = ["-x.txt"]
If no pattern declares --, the -- is dropped: with my_program <file>..., a -- -b gives
file = ["a", "-b"]. Remember that rash consumes the first -- itself:
rash my_program.rh -- a -- -b.
Optional elements
Elements (arguments, commands) enclosed with square brackets [] are marked as
optional. It does not matter if elements are enclosed in the same or different pairs of brackets.
The following examples are equivalent:
Usage: my_program [command --option]
Usage: my_program [command] [--option]
Optional elements can be nested:
Usage: my_program [command [--option]]
In this example, --option can only be used if command is provided.
Optional elements take arguments greedily, left to right: with my_program [<source>] [<dest>], a
single argument fills <source>. They give arguments back when a later required element needs
them, so my_program [<source>] <dest> with one argument fills <dest>. See
Choosing between matches.
Required groups
All elements are required by default if not included in brackets []. However, sometimes it is
necessary to mark elements as required explicitly with parentheses (). For example, when you
need to group mutually-exclusive elements:
Usage: my_program (--either-this <and-that> | <or-this>)
Another use case is when you need to specify that if one element is present, then another one is required, which you can achieve as:
Usage: my_program [(<one-argument> <another-argument>)]
In this case, a valid program invocation could be with either no arguments, or with both arguments together.
Mutually exclusive elements
Mutually-exclusive elements can be separated with a pipe | as follows:
Usage: my_program go (up | down | left | right)
Use parentheses () to group elements when one of the mutually exclusive cases is required.
Use brackets [] to group elements when none of the mutually exclusive cases is required:
Usage: my_program go [up | down | left | right]
| Note that specifying several patterns works exactly like pipe “ | ”, that is: |
Usage:
my_program run [fast]
my_program jump [high]
is equivalent to:
Usage: my_program (run [fast] | jump [high])
Repeatable elements
Use ellipsis ... to specify that the argument (or group of arguments) to the left could be
repeated one or more times:
Usage:
my_program open <file>...
my_program move (<from> <to>)...
You can flexibly specify the number of arguments that are required. Here are 3 (redundant) ways of requiring zero or more arguments:
Usage:
my_program [<file>...]
my_program [<file>]...
my_program [<file> [<file> ...]]
One or more arguments:
Usage: my_program <file>...
Two or more arguments (and so on):
Usage: my_program <file> <file>...
When parsed, repeatable positional arguments will be available as arrays in your program:
# If invoked as: my_program open file1.txt file2.txt file3.txt
# The variables available would be:
file = ["file1.txt", "file2.txt", "file3.txt"]
Commands and option flags that can occur more than once are counted instead:
Usage:
my_program go (up | down)...
my_program [-v...]
# my_program go up up down -> up = 2, down = 1
# my_program -vvv -> options.v = 3
An element written more than once in a pattern counts as repeatable too: [<x>] [<x>] produces a
list and [-v] [-v] a count. An option cannot be given more times than its pattern allows:
my_program [-v] rejects -v -v.
The [options] shortcut
[options] stands for every option described in the help text that no usage pattern writes
explicitly. The options can be given in any order:
Usage: my_program [options] <file>
Options:
-v --verbose Enable verbose output
-n --dry-run Do not change anything
Here my_program -n -v file.txt and my_program --verbose file.txt are valid, but options after
<file> are not. An option written explicitly in any pattern is left out of [options] in every
pattern: with my_program run [-v] and my_program list [options], list -v is rejected.
Argument formatting rules
When writing your usage patterns, follow these formatting rules:
- Command names are lowercase ASCII words of letters and digits, starting with a letter and
joined by
-or_(my-command,step2) - Positional arguments follow the same rules, written as
<lowercase-with-hyphens>orUPPERCASE - Option flags begin with
-or-- - Long option names use hyphens for spaces (
--long-option) - When option flags accept values, format as
--option=VALUEor-o VALUE, and describe them in the options section
Advanced usage patterns
Complex command-line interfaces can combine all the elements described above:
Usage:
program ship new <name>...
program ship <name> move <x> <y> [--speed=<kn>]
program ship shoot <x> <y>
program mine (set|remove) <x> <y> [--moored|--drifting]
program -h | --help
program --version
Options can be described in a separate section:
Usage: my_program [options] <command>
Options:
-h --help Show this help message
--version Show version information
-v --verbose Enable verbose output
-o FILE, --output=FILE Write output to FILE
This defines which flags are available and how they should be parsed, especially for options that take arguments.