views:

1030

answers:

9

Vote up the one you like best! Use comments to justify your choice.

As I know there are two types of command line commands. If you can think of another one, post an example (as a community-wiki answer).

A: 

Parameter commands, like ls -la or tar xvf hello.tar.

Shog9
+6  A: 

I prefer

command ... -flag ... -option value ... parameter ...

Like:

mount -f -t ntfs /dev/hda1 /mnt/windows
git commit -a -m "committing"

Generally because the large majority of commands work this way. It also is easy to see what's a flag, an option, or a parameter, and it doesn't contain any unnecessary "human readable" syntax that, in my opinion, only serves to clutter the actual command.

Examples of commands I don't like:

dd if=/this/file of=/that/file bs=1024
daemon start at 10:00

I dislike the dd command because the syntax of the parameters is at odds with the established convention (though, to be fair, when dd was first written, said conventions didn't exist). The second, as I stated, I don't like because the word "at" is completely extraneous and requires time to read and mentally parse. (this is also the same reason why I hate the loop macro in Common Lisp)

Kyle Cronin
+2  A: 

Human readable commands like: daemon start at 10:00

Shog9
+2  A: 

Far and away "human readable commands"; I can type fast, but remembering huge numbers of "encrypted" words that have little or nothing to do with the effect they actually have is hard.

Software Monkey
It's all about remembering the mnemonics... and hoping the authors are consistent. I know I get pissed because `wget -o <file>` means "use <file> for progress logging", whereas I'm used to ld, gcc, and numerous other programs wherein `-o <file>` means "put output into <file>".
Tom
+6  A: 

GNU-style long options

ls --all --color=auto
Tom
+2  A: 

Commands in a separate text file:

ld @ldfile

...where ldfile is a text file that contains command-line arguments itself (generally because argv is limited to 4096 or some relatively small number on many machines).

Both GNU and Microsoft's compilers and linkers will do this, since command line arguments for compilers and linkers can get huge.

Tom
+5  A: 

How many different types of options do you recognize? I can think of many, including:

  • Single-letter options preceded by single dash, groupable when there is no argument, argument can be attached to option letter or in next argument (many, many Unix commands; most POSIX commands).
  • Single-letter options preceded by single dash, grouping not allowed, arguments must be attached (RCS).
  • Single-letter options preceded by single dash, grouping not allowed, arguments must be separate (pre-POSIX SCCS, IIRC).
  • Multi-letter options preceded by single dash, arguments may be attached or in next argument (X11 programs).
  • Multi-letter options preceded by single dash, may be abbreviated (Atria Clearcase).
  • Multi-letter options preceded by single plus (obsolete).
  • Multi-letter options preceded by double dash; arguments may follow '=' or be separate (GNU utilities).
  • Options without prefix/suffix, some names have abbreviations or are implied, arguments must be separate. (AmigaOS Shell)

Options taking an optional argument sometimes must be attached, sometimes must follow an '=' sign. POSIX doesn't support optional arguments meaningfully (the POSIX getopt() only allows them for the last option on the command line).

All sensible option systems use an option consisting of double-dash ('--') alone to mean "end of options" - the following arguments are "non-option arguments" (usually file names) even if they start with a dash. (I regard supporting this notation as an imperative.)

Many but not all programs accept single dash as a file name to mean standard input (usually) or standard output (occasionally). Sometimes, as with GNU 'tar', both can be used in a single command line:

tar -cf - -F - | ...

The first solo dash means 'write to stdout'; the second means 'read file names from stdin'.

Some programs use other conventions - that is, options not preceded by a dash. Many of these are from the oldest days of Unix. For example, 'tar' and 'ar' both accept options without a dash, so:

tar cvzf /tmp/somefile.tgz some/directory

The dd command uses opt=value exclusively:

dd if=/some/file of=/another/file bs=16k count=200

Some programs allow you to interleave options and other arguments completely; the C compiler, make and the GNU utilities run without POSIXLY_CORRECT in the environment are examples. Many programs expect the options to precede the other arguments.


I don't have strong preferences between the different systems. When there are few enough options, then single letters with mnemonic value are convenient. GNU supports this, but recommends backing it up with multi-letter options preceded by a double-dash.

There are some things I do object to. One of the worst is the same option letter being used with different meanings depending on what other option letters have preceded it. In my book, that's a no-no, but I know of software where it is done.

Another objectionable behaviour is inconsistency in style of handling arguments (especially for a single program, but also within a suite of programs). Either require attached arguments or require detached arguments (or allow either), but do not have some options requiring an attached argument and others requiring a detached argument. And be consistent about whether '=' may be used to separate the option and the argument.

As with many, many (software-related) things - consistency is more important than the individual decisions.


Whatever you do, please, read the TAOUP's Command-Line Options and consider Standards for Command Line Interfaces. (Added by J F Sebastian - thanks; I agree.)

Jonathan Leffler
@J F Sebastian: thanks for the addition. I absolutely agree about reading both references, and sticking with a standard (consistency with what other applications do).
Jonathan Leffler
You should probably also mention -- as the indication of the end of any options and the beginning of the non-option arguments.
Hudson
@Hudson: as noted in the paragraph starting 'All sensible option systems use an option consisting of double-dash alone to mean "end of options"'? :D Do I need to make that clearer?
Jonathan Leffler
Uhm, I'll go practice my reading comprehension skills. Sorry about that.
Hudson
@Hudson: I did edit it to make it clearer - though the info was there already.
Jonathan Leffler
A: 

In addition to command line options and parameters, if your command has the potential to have multiple options or long argument list, please provide an option (as Ken G mentioned) to put options and parameters in a separate file. This is usually called a 'response' file and I usually use a .rsp extension to detect that the argument is a response file

I.e.:   command my_options.rsp

rather than @ symbol (although I kind of like this too) and rather than a switch (I.e. -r my_options) unless .rsp is a valid extension for a filename argument.

On another note, I prefer options and their arguments to be separated by a symbol or space, not run together.

I.e. command -o:argument 
or   command -o argument
or   command -option:argument
not  command -oargument

I also prefer multiple character option tags to avoid ambiguities If you use very short tags, try to be consistent with option tags of other similar commands I.e. -a for all, -v for verbose, -r for recursive, ? for help (depending on the OS/shell). and avoid using a tag commonly used by other (especially similar) commands, for a completely different option/function.

Sometimes I have + and - to enable/disable an option,

I.e. command +option        command option:on
or   command  option:on     command option:off
Roger Nelson
A: 

My favorite, by a large margin, is the command line syntax of PowerShell.

A cmdlet's parameter list is available as metadata to the shell, so you can get completion while typing. For example, type:

PS> dir -R[TAB]

and you get

PS> dir -Recurse

You can use the smallest unique prefix, so you can write:

PS> del -R deleteme   # recursive delete

and get a useful error if it's not unique:

PS> del deleteme -F
Remove-Item : Parameter cannot be processed because the parameter name 'F' is ambiguous. Possible matches include: -Filter -Force.

If a parameter takes an argument that is a .NET enum type, you can get help:

PS> Set-ExecutionPolicy -ExecutionPolicy X
Set-ExecutionPolicy : Cannot bind parameter 'ExecutionPolicy'. Cannot convert value "X" to type "Microsoft.PowerShell.ExecutionPolicy" due to invalid enumer
ation values. Specify one of the following enumeration values and try again. The possible enumeration values are "Unrestricted, RemoteSigned, AllSigned, Def
ault, Restricted, Bypass".

If you pass an argument for a parameter without the parameter, it will be filled in positionally:

PS> Set-ExecutionPolicy Unrestricted    # OK: Unrestricted applies to -ExecutionPolicy

You can also use this syntax if you prefer:

PS> Set-ExecutionPolicy -ExecutionPolicy:Unrestricted

It's easy to type commands quickly at the command line, while also being easy to make scripts easy to read.

You don't have to memorize a short name (-a) and a long name (--all) like you do for GNU tools.

There are a set of default parameters that apply to all cmdlets, such as -Verbose, -Debug, -ErrorAction, etc. These can be manipulated in global way by environment variables, such as $VerbosePreference.

Parameter handling is consistent across all cmdlets.

In PowerShell V2, the same power is available to scripts and functions (called "Advanced Functions"), so you don't need C# to do this.

Awesome.

Jay Bazuzi