3

There are lots of GUI best practices. I am looking for best practices when developing a command line program.

For example, if I were creating a backup program what is best?

Consideration 1, invocation:

program.exe backup

program.exe /backup

program.exe -backup

program.exe --backup

Consideration 2, parameters:

program.exe backup "C:\file1.txt" "C:\file1.bak" (implicit source and destination)

program.exe backup -source "C:\file1.txt" -destination "C:\file1.bak" (explicit)

program.exe backup -source "C:\file1.txt" "C:\file2.txt" "C:\file3.txt" -destination "C:\files.bak" (multiple sources)

program.exe backup -source "C:\file1.txt" -source "C:\file2.txt" -source "C:\file3.txt" -destination "C:\files.bak" (multiple sources, alternative syntax)

Consideration 3, chaining:

program.exe backup "C:\file1.txt" "C:\file1.bak" backup "C:\file2.txt" "C:\file2.bak" (should this be allowed?)

Consideration 4, typing economy:

program.exe backup

program.exe bkp

program.exe b (should all these be aliases to the same command?)

DanDan
  • 10,462
  • 8
  • 53
  • 69
  • Which platform? Different platforms have different expectations in CLIs. Your examples use "-" for command-line options mostly,which is a Unix/Linux thing, but use Windows filenames. – David Thornley Sep 03 '10 at 15:17
  • Platform neutral would be ideal, but I see this may not be possible. For now, Windows is of most concern to me. – DanDan Sep 03 '10 at 15:35
  • if Windows is your primary concern, I'd **strongly** suggest you look at the link to command line parsers in my answer. There's little point re-inventing the wheel for something like this =) Don't write code that someone's already written for you.. Even if you're not working specifically in C#/the CLR, it may be that you can use the libraries, or similar ones for your purpose. – Rob Sep 03 '10 at 15:43

7 Answers7

2

I'd always prefer what's (in order of importance from most to least):

  • Most understandable by the end user
  • Least ambiguous
  • Follows the conventions of the platform being coded against
  • Easiest to parse in my code

So on Windows I'd go for / as the prefix (follows the conventions), /source and /destination (most understandable AND least ambiguous) and not allow chaining as that makes for parsing complexity, so:

program.exe /backup /source:"c:\source" /destination:"c:\destination"

By all means also permit abbreviated versions of the parameter names, so you could allow the above to be shrunk down to:

program.exe /b /s:"c:\source" /d:"c:\destination"

But don't make it any more arcane than that. Also, include a /? parameter that can be used to list the syntax for your program. As Peter M pointed out in the comments on my answer, it's a good idea to do the same as /? when the user calls your program without specifying any parameters. Nothing's less helpful and more frustratingly useless than running a CLI program and receiving:

Program Name v1.01

No parameters specified, use /? for help

One other important thing to consider, tied to the final point, would be: don't reinvent the wheel. There are innumerable Command Line Parsers out there, take a look at the answers to this question for a starting point (if you're using C# targeting Windows). Don't do a mediocre job of doing something that someone else has already done a good job of doing.

Community
  • 1
  • 1
Rob
  • 45,296
  • 24
  • 122
  • 150
  • I also default to the /? equivalent when no parameters are supplied – Peter M Sep 03 '10 at 15:57
  • @Peter M - good point. I think I'll add that to my answer - I can't believe I didn't think of that =) – Rob Sep 03 '10 at 15:58
  • @Peter M, and done! Thanks for that =) It also allowed me to have a small rant about programs that give *useless* output when called without any parameters ;=) – Rob Sep 03 '10 at 16:00
  • I went for the NDesk.Options library. Thanks! – DanDan Sep 06 '10 at 12:53
1

I prefer using double dashes for long names in addition to single character equivalent short forms with single dashes.

If you are making something non trivial I'd also suggest to always use a switch name and have switch values optional depending on what the switch does.

So for example to backup support both of:

  program.exe --backup   
  program.exe -b 

And to restore support both of:

  program.exe --restore "5/6/2010"
  program.exe -r "5/6/2010"

For help support both of:

  program.exe --help
  program.exe -h
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
1

Definitely parameters and with /Help switch to explain usage. So that end user have freedom of which parameter to put first and hence not force a particular order of the parameters

Julius A
  • 38,062
  • 26
  • 74
  • 96
1
  • Allow --long-option-name and -lon for optional parameters.
  • Create backup.exe instead of using backup as a command to program.exe.
  • Use standard input and standard output as default input and output files.
  • Use current directory as default location for operations.

That's for general UNIX/Linux rules. For Windows, they are completely different.

  • Don't use /source and /destination. Imagine the hell it would be if cp (copy) required it.
Didier Trosset
  • 36,376
  • 13
  • 83
  • 122
1

In general, you should stay within the conventions of the platform. Unfortunately, Microsoft Windows has been pretty inconsistent about command-line interfaces! Therefore, you should be equally inconsistent. I think the ideal model in this case is the famously inconsistent dd:

dd if=C:\file1.txt of=C:\file2.bak

There's nothing else quite like it.

Ken
  • 1,159
  • 1
  • 9
  • 13
0

Well for starters I would ditch the program.exe syntax and just go for backup.exe

I like the /option:<value> syntax myself. I'd probably like to be able to the following:

backup /d:"c:\mydirectory" /o:"c:\mybackup.bak"
backup /f:"c:\mydiredctory\myfile.txt" /o:"c:\mybackup.bak"
backup /f:"mydiredctory\myfile.txt,mydiredctory\myfile2.txt" /o:"c:\mybackup.bak"
Micah
  • 111,873
  • 86
  • 233
  • 325
  • and if the `backup`, `restore` and `list-contents-of-backup` functions are required to be in one executable? =) By your argument, `svnadmin` (for example) should be split out into quite a few separate executables. – Rob Sep 03 '10 at 15:14
  • @Rob: In Unix/Linux systems, you leave them as one executable, symlink them to different names, and look at `argv[0]` or the equivalent to see how you're being called. – David Thornley Sep 03 '10 at 15:17
  • If we were talking about multiple commands then yes. But in all fairness no one ever mentioned restoring backups, only creating them. I didn't want to code for features that weren't part of the spec. =) – Micah Sep 03 '10 at 15:34
0

I recommend finding a library that will allow you to define your command-line parameters and parse them properly, while also printing out usage instructions that define all of your parameters to the users of your application. There should be plenty of open source libraries available for multiple languages and platforms.

Bernard
  • 7,908
  • 2
  • 36
  • 33