Skip to main content
Small typos & formatting
Source Link
Glorfindel
  • 3.2k
  • 6
  • 26
  • 33
  • command line completion (to help with a complete set of options)

    command line completion (to help with a complete set of options)

  • man page

    man page

  • useful "usage messages" that "guide you" like git's:

    useful "usage messages" that "guide you" like git's:

    On branch master
     Changes to be committed:
     (use "git reset HEAD <file>..." to unstage)
    
    modified: hello.py
    
     Changes not staged for commit:
     (use "git add <file>..." to update what will be committed)
     (use "git checkout -- <file>..." to discard changes in working directory)
    
    modified: main.py
    
     Untracked files:
     (use "git add <file>..." to include in what will be committed)
    
    hello.pyc
    
    On branch master
     Changes to be committed:
     (use "git reset HEAD <file>..." to unstage)
    
    modified: hello.py
    
     Changes not staged for commit:
     (use "git add <file>..." to update what will be committed)
     (use "git checkout -- <file>..." to discard changes in working directory)
    
    modified: main.py
    
     Untracked files:
     (use "git add <file>..." to include in what will be committed)
    
    hello.pyc
  • command line completion (to help with a complete set of options)
  • man page
  • useful "usage messages" that "guide you" like git's:
    On branch master
     Changes to be committed:
     (use "git reset HEAD <file>..." to unstage)
    
    modified: hello.py
    
     Changes not staged for commit:
     (use "git add <file>..." to update what will be committed)
     (use "git checkout -- <file>..." to discard changes in working directory)
    
    modified: main.py
    
     Untracked files:
     (use "git add <file>..." to include in what will be committed)
    
    hello.pyc
  • command line completion (to help with a complete set of options)

  • man page

  • useful "usage messages" that "guide you" like git's:

    On branch master
     Changes to be committed:
     (use "git reset HEAD <file>..." to unstage)
    
    modified: hello.py
    
     Changes not staged for commit:
     (use "git add <file>..." to update what will be committed)
     (use "git checkout -- <file>..." to discard changes in working directory)
    
    modified: main.py
    
     Untracked files:
     (use "git add <file>..." to include in what will be committed)
    
    hello.pyc
    

But I understand that your program (or your example) is one of those complex CLI apps that have actions/commands with their own parameters. In this kind of programs thisprogram, positional arguments behave like "default" command line options when no option is used.

I believe some CLI programs behave like that (postgres comes to mind besides git).

The more complex the basic behavior of a CLI program is, the more it relies on named, non-positional command-line options. For example, git, has a complex interface and no option is positional, although one could consider the big "options section" comes first thanthen the big "command and args" section.

git [--version] [--help] [-C <path>] [-c <name>=<value>] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p|--paginate|--no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] [--super-prefix=<path>] <command> [<args>]

git [--version] [--help] [-C <path>] [-c <name>=<value>]
    [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
    [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
    [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
    [--super-prefix=<path>]
    <command> [<args>]

looks like there's a single mandatory positional parameter but what my parser really does itis that it assumes some mandatory options

  • command line completion (to help with a completcomplete set of options)
  • man page
  • useful "usage messages" thanthat "guide you" like git's:

     On branch master
     Changes to be committed:
     (use "git reset HEAD <file>..." to unstage)
    
    modified: hello.py
    
     Changes not staged for commit:
     (use "git add <file>..." to update what will be committed)
     (use "git checkout -- <file>..." to discard changes in working directory)
    
    modified: main.py
    
     Untracked files:
     (use "git add <file>..." to include in what will be committed)
    
    hello.pyc
 

ThisThese messages tell you what to do next or what is missing.

Additionally some CLI utilities, like for example some of Oracle's utilities, can as an alternative accept a "parfile" in which all parameters and values can be saved in a key-value file and passed as an argument instead of having a very long series of options and arguments, I particularly use this in my designs.

But I understand that your program (or your example) is one of those complex CLI apps that have actions/commands with their own parameters. In this kind of programs this positional arguments behave like "default" command line options when no option is used.

I believe some CLI programs behave like that (postgres comes to mind besides git)

The more complex the basic behavior of a CLI program is, the more it relies on named, non-positional command-line options. For example, git, has a complex interface and no option is positional, although one could consider the big "options section" comes first than the big "command and args" section.

git [--version] [--help] [-C <path>] [-c <name>=<value>] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p|--paginate|--no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] [--super-prefix=<path>] <command> [<args>]

looks like there's a single mandatory positional parameter but what my parser really does it that it assumes some mandatory options

  • command line completion (to help with a complet set of options)
  • man page
  • useful "usage messages" than "guide you" like git's:

 On branch master
 Changes to be committed:
 (use "git reset HEAD <file>..." to unstage)

modified: hello.py

 Changes not staged for commit:
 (use "git add <file>..." to update what will be committed)
 (use "git checkout -- <file>..." to discard changes in working directory)

modified: main.py

 Untracked files:
 (use "git add <file>..." to include in what will be committed)

hello.pyc
 

This messages tell you what to do next or what is missing.

Additionally some CLI utilities, like for example some Oracle's utilities, can as an alternative accept a "parfile" in which all parameters and values can be saved in a key-value file and passed as an argument instead of having a very long series of options and arguments, I particularly use this in my designs.

But I understand that your program (or your example) is one of those complex CLI apps that have actions/commands with their own parameters. In this kind of program, positional arguments behave like "default" command line options when no option is used.

I believe some CLI programs behave like that (postgres comes to mind besides git).

The more complex the basic behavior of a CLI program is, the more it relies on named, non-positional command-line options. For example, git, has a complex interface and no option is positional, although one could consider the big "options section" comes first then the big "command and args" section.

git [--version] [--help] [-C <path>] [-c <name>=<value>]
    [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
    [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
    [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
    [--super-prefix=<path>]
    <command> [<args>]

looks like there's a single mandatory positional parameter but what my parser really does is that it assumes some mandatory options

  • command line completion (to help with a complete set of options)
  • man page
  • useful "usage messages" that "guide you" like git's:
    On branch master
     Changes to be committed:
     (use "git reset HEAD <file>..." to unstage)
    
    modified: hello.py
    
     Changes not staged for commit:
     (use "git add <file>..." to update what will be committed)
     (use "git checkout -- <file>..." to discard changes in working directory)
    
    modified: main.py
    
     Untracked files:
     (use "git add <file>..." to include in what will be committed)
    
    hello.pyc

These messages tell you what to do next or what is missing.

Additionally some CLI utilities, like for example some of Oracle's utilities, can as an alternative accept a "parfile" in which all parameters and values can be saved in a key-value file and passed as an argument instead of having a very long series of options and arguments, I particularly use this in my designs.

Source Link
Tulains Córdova
  • 39.5k
  • 13
  • 99
  • 155

Historically, and as other users have answered, programs have used positional arguments for mandatory arguments and command-line options for optional stuff.

Ancient programs and commands like cp show clearly in their syntax that SOURCE and DEST are positional and mandatory, whereas all the rest are options:

cp [OPTION]... [-T] SOURCE DEST

Later as complexity increased, some CLI programs began to use two-hyphen options with longer names as they ran out of single letters (see this useful answer in a sister site), with existing one hyphen switches gaining a longer, self documenting alternative:

-f, --force

But I understand that your program (or your example) is one of those complex CLI apps that have actions/commands with their own parameters. In this kind of programs this positional arguments behave like "default" command line options when no option is used.

One could see --action in your second example as the default option that is omitted in the first example where no option was used, actually enforcing a mandatory option.

Also --username can be seen as the default sub-option for --action. The parser expands omitted options as being the default ones.

I believe some CLI programs behave like that (postgres comes to mind besides git)

The more complex the basic behavior of a CLI program is, the more it relies on named, non-positional command-line options. For example, git, has a complex interface and no option is positional, although one could consider the big "options section" comes first than the big "command and args" section.

git [--version] [--help] [-C <path>] [-c <name>=<value>] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p|--paginate|--no-pager] [--no-replace-objects] [--bare] [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>] [--super-prefix=<path>] <command> [<args>]

The example you give is a git-style app, with a set of commands passed as switches that themselves have several options.

So to answer your question I dare to say nowadays, newer CLI apps and those that have complex behavior tend to rely heavily on named non-positional options (some, like git use "commands" that don't use hyphens).

I design and program complex command-line apps and I use named options with some of them being mandatory and used as default when users don't specifically writes them, for example:

$ dbsearch production

looks like there's a single mandatory positional parameter but what my parser really does it that it assumes some mandatory options

$ dbsearch -l -a production

and its equivalent

$ dbsearch --list --search_argument production

Some of the following is almost always considered part of a good CLI interface:

  • command line completion (to help with a complet set of options)
  • man page
  • useful "usage messages" than "guide you" like git's:

On branch master
 Changes to be committed:
 (use "git reset HEAD <file>..." to unstage)

modified: hello.py

 Changes not staged for commit:
 (use "git add <file>..." to update what will be committed)
 (use "git checkout -- <file>..." to discard changes in working directory)

modified: main.py

 Untracked files:
 (use "git add <file>..." to include in what will be committed)

hello.pyc

This messages tell you what to do next or what is missing.

Additionally some CLI utilities, like for example some Oracle's utilities, can as an alternative accept a "parfile" in which all parameters and values can be saved in a key-value file and passed as an argument instead of having a very long series of options and arguments, I particularly use this in my designs.