I generally agree with the points you made in Conventions for Command Line Options, but am curious about your views on one issue: when following those conventions, is there any way to pass multiple arguments to a single instance of an option? (I realize you can pass the same option multiple times, but that's not what I'm asking about.) The reason I ask is to support the output of shell globing; it would be nice if > --input-files *.jpg were parsed as multiple options being passed to --input-files rather than as a single argument to --input-files followed by multiple positional arguments. But, unless I'm missing something, I don't believe there's a way to support using multiple values like that while following the conventions you laid out. Nor can I think of a way to do so without guessing in the way argparse does -- which would create obvious difficulties with certain filenames in the example above, in addition to the other issues you raise. So do you just accept that there's no way to support that usage pattern and maintain that the costs of supporting it outweigh any benefits? Or am I missing some way to support it while following the conventions you laid out? I would welcome other perspectives on this as well. Best regards, Daniel
> --input-files *.jpg This has no way to indicate where the arguments stop such that option processing can continue, so this option must go last. If it must go last, then these are really just positional arguments. If you do choose some sentinel to mark the end (perhaps "--") then there's the risk of an argument unintentionally matching as a sentinel, such as blog expansion. As you noted, stopping at the first option-like argument (a la argparse) is similarly unsound. You mentioned repeated arguments, probably the most conventional way to supply multiple arguments for a particular option. For instance, there's ffmpeg's -i option. Though as you also noticed, this isn't friendly to globbing. Another is to use a custom, non-space delimiter that the shell won't split, such as a comma, so that the application can do its own splitting on the argument. For instance, gcc's -Wl option. Though again, not friendly to globbing. Some programs that may need to accept more arguments than the operating system allows but cannot be run multiple times (e.g. via xargs) may accept a glob pattern as an argument and expand the pattern itself. In this case usage would look like: > --input-files '*.jpg' For instance, ImageMagick may potentially have very many inputs and so it optionally (though imperfectly) accepts glob patterns. > So do you just accept that there's no way to support that usage pattern > and maintain that the costs of supporting it outweigh any benefits? Yes, I think that accurately summarizes my position. Popular programs can get away with custom conventions (e.g. gcc) so long as they consistently stick to them, but less popular programs with unique, unusual conventions demand undue extra headspace as users code switch between conventions. For instance, Go's flag package still regularly trips me up until I remember I'm dealing with a Go program. Arbitrary argument lists should be positional arguments. If you need multiple such lists (e.g. multiple inputs and multiple outputs), all but one list should be relegated to a repeated arguments — preferably the ones least likely to be used with glob expansion.
Thanks very much for the helpful and through reply! This (along with your post) has been very helpful in getting my head around all of this, and has definitely impacted the design decisions I'm making as I work to expand the argument parser built in to the Raku standard library. >> --input-files *.jpg > > This has no way to indicate where the arguments stop such that option processing can continue, so > this option must go last. If it must go last, then these are really just positional arguments. > [snip] > Arbitrary argument lists should be positional arguments. If you need multiple such lists (e.g. > multiple inputs and multiple outputs), all but one list should be relegated to a repeated arguments > — preferably the ones least likely to be used with glob expansion. That's a very helpful way of putting it, and makes me realize that subcommands (in the style of git and similar commands can also be useful. If a CLI needs to be able to accept multiple argument lists but _only one in any given invocation_, then it can use a subcommand followed by positional arguments. (Or, and this is effectively the same thing, have a boolean option that changes the meaning of the positional arguments.) That doesn't address the use case of needing to process multiple lists in the same invocation, but it at least narrows the scope of the problem. Thanks again! Daniel