5.2 KiB
Argument Types and Behaviour in Coreutils
The coreutils are specified by POSIX and have various implementations. We want
to be compatible with the GNU implementation. Generally, these utils use
getopt_long function provided by GNUlib. This is a fairly simple parser, that
you can repeatedly call to iterate over the options passed to the util.
Default Behaviour
This construction gives the follow default behaviours:
--helpand--versionare used as the flags for, well, help and version, respectively.-hand-Vare NOT excepted and sometimes even used for other purposes than showing help and version.- Values with leading hyphens are accepted by default.
getopt_longdoes not do any checking of conflicting arguments. Hence, all arguments have overriding behaviour, including overriding themselves.- Long options are inferred from unambiguous prefixes. For example,
ls --groupis inferred tols --group-directories-firstbecause there is no other long option starting withgroup. - The help string is written by hand and not provided by
getopt_long. To their credit, the GNU authors have put great effort into standardizing these strings.
Many-to-many relationship
In the coreutils, there is a very loose coupling between the arguments and their
effect in the program. Take the snippet from cat below, for example. Settings
can be changed by multiple options (e.g. show_nonprinting is set by -t, -v
and -A). This leads to a many-to-many relationship: each option can change
multiple settings and each settings can be changed by multiple options.
switch (c) {
case 't':
show_tabs = true;
show_nonprinting = true;
break;
case 'v':
show_nonprinting = true;
break;
case 'A':
show_nonprinting = true;
show_ends = true;
show_tabs = true;
break;
case 'E':
show_ends = true;
break;
case 'T':
show_tabs = true;
break;
}
Argument Types
Flags
There are many simple flags that do not take any values. For example, the flags
from cat above are all flags. They can have both long and short versions
(--show-nonprinting & -v), but they can also have just one of the two.
Some flags are hidden, like tail's ---presume-input-pipe option. These
hidden arguments also have 3 leading hyphens.
Options with values
Some options take values. Most of the time, this is just a long options. Some examples:
lshas-w, --width=COLS, where the value is required for both the short and long option.lshas-F, --classify[=WHEN], where the value is optional for the long option and the short option does not take a value.lshas--hyperlink[=WHEN], which does not have a short version (and an optional value).mktemphas-p DIR, --tmpdir[=DIR], where the value is required for the short option and optional for the long option.datehas-I[FMT], --iso-8601[=FMT], where the value is optional for both the short and long option.
If the option takes one of several possible values, these values are inferred
from unambiguous prefixes. For example, ls --color=y can be used as shorthand
for ls --color=yes.
Positional arguments
Some utils take positional arguments, which might be required.
archtakes no positional arguments.comm FILE1 FILE2takes 2 required positional arguments.tr SET1 [SET2]has 1 required and 1 optional positional argument.uniq [INPUT [OUTPUT]]takes 2 optional positional arguments.ls [FILE]...takes 0 or more positional arguments.cp SOURCE... DESTtake 1 or more source arguments and 1 required destination argument, however,cp -t DIRECTORY SOURCE...does not have the destination argument.timeout DURATION COMMAND...takes one 1 required duration and a trailing argument of minimal 1 value. Any options appearing after the first value ofCOMMANDshould be parsed as part ofCOMMAND.who [ FILE | ARG1 ARG2 ]either takes 1FILEargument or 2ARGarguments.
Deprecated syntax +N and -N
Some utils (e.g. head, tail, kill, fold and uniq) support an old
deprecated syntax where numbers can be directly passed as arguments as a
shorthand. For example, uniq +5 is a shorthand for uniq -s 5 and uniq -5
is short for uniq -f 5.
These all behave slightly differently.
headandtailonly accept this if it is the first argument and either 1 or 2 arguments are given.- In
foldthe-Nmust be standalone (e.g.-10bis rejected), but can appear at any position. - In
kill, the same rules asfoldapply, but it can also be a name instead of a number. - In
uniq, the syntax does not need to stand alone and is additive in a weird way, because they hack-22as-2 -2so each flag-1...-9multiplies the previous by 10 and adds itself. I'm not sure that we need to support this. Doing something like whatfoldandkilldo is probably fine. Also note that to make it extra confusing, the+variant works likefold. prthe behaviour is similar touniq.splitseems to be somewhere betweenuniqandfold. It accepts things like-x10xcorrectly, but it doesn't do the additive thing fromuniqacross multiple occurrences. Basically, it's very clever and cursed.