Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

When writing tools for the CLI of UNIX, how should I make the program print out help and/or usage?

I usually use fprintf(stderr, "help text here");, but there are several issues with that.

  • First, I'm not sure, whether I should use stderr. Is that OK, or should I use stdout?
  • As you can imagine, the help text is quite long, depending on how many options the tool has. Now, I usually, just put several "strings like that\n" in the second parameter. This however, fills my source code with fifty or more lines of help text. It is not easy manageable at all. What should I do instead?
  • When a tool is not written in C or a C-like language, I tend to use here-docs where possible (most prominently with Perl). I can't use that in C, but is there something like that, that I could use?
  • I was considering putting it in a headerfile.h inside a #define HELP "help text here", I've never seen it in the wild, don't know whether I should actually use that.

Ideally, I could put the text in an external file, and include it. Using #include for that seems wrong, though. What should I do then?

The idea is, to have a help text, that is easily manageable. Having it inside the source code isn't really convenient.

share|improve this question
1  
What's so bad about 50 lines in your source code? Just put it at the end. It's not like you're going to have to mess with it on a regular basis. –  whatsisname Feb 28 '12 at 23:40
1  
@whatsisname usage, help for normal and longopts. I end up having around 200 lines of strings in the sourcode. Aside from that, I just don't think this is best practice, etc. There must be a more efficient way of putting in help texts, etc. –  polemon Feb 28 '12 at 23:58
add comment

5 Answers

up vote 4 down vote accepted

Inspire Yourself from your Target Platform's Internals

Have a look at the BSDs' source code. For instance, here are the:

  • usage(void) for NetBSD's /usr/bin/uname tool [source]:

    usage(void)
    {
        fprintf(stderr, "usage: uname [-amnprsv]\n");
        exit(EXIT_FAILURE);
    }
    
  • usage(void) for NetBSD's /usr/bin/telnet [source]

  • usage(void) for OpenBSD's /bin/ls [source]

Have a Look at Alternatives

And decide for yourself whether they're better or worse. You can use Google CodeSearch to find others, like:

As you can see, different style between these and the BSD systems integrated tools listed above. It doesn't mean you have to follow one or the other. But usually it's good to look around, and settle for the consistent solution.

A non-standard solution to the 50 lines of help...

If you don't like to avoid 50 lines of text, you could simply read the help from a text file (in plain text, or maybe directly parse the man's source if you created one). I find that a rather elegant way (as you can even look up the text doc), however for core systems programs that would make them inherently unsafe and introduce a point of failure. Other people will argue it's heavy for a usage or help message, but it's not like these are called in fast tight loops...

When in doubt, follow the giants.

share|improve this answer
    
+1 Having a method to store that's way better than mine. –  Spencer Rathbun May 11 '12 at 18:01
    
@SpencerRathbun: thanks. I like this approach as well, especially when you version the help, need to internationalize or work with other people to manage the help. Makes it easy. But do keep in mind that you introduce some I/O code to open/read/close the resources, and that it may complicate things and possibly introduce security holes. In the general case and for small apps though, I mostly think it's worth it. –  haylem May 22 '12 at 12:03
add comment

I use stdout, because a help is not an error.

If this is a long help in C, I try to mimic here-docs:

printf("This is the help for MyWonderfulApp\n"
       "Options are:\n"
       "    --help: display what you are reading now\n"
       "    --quiet: output nothing\n");

But most of the time I write a man page using nroff -man dedicated tags. The in-app help simply consists in refering to that man page.

share|improve this answer
1  
+1 for learning the lost art of writing manual pages. –  Blrfl May 11 '12 at 13:57
    
But help is not necessarily desirable standard output, is it? How about stdlog? –  greyfade Dec 5 '13 at 20:23
    
@greyfade: Is stdlog standard C? –  mouviciel Dec 5 '13 at 20:39
    
@mouviciel: ... I thought it was. I guess not. C++ has a related standard stream (cin, cout, cerr, and clog), so I guess I thought stdlog was in the C standard. My bad. –  greyfade Dec 5 '13 at 21:27
add comment

If I'd be you I'd just opened up sources of grep, tail, cat, your_other_favorite_unix_shell_command to see how it's done there. I'm pretty sure their ways are pretty well thought out and can be maintained by many people.

About stderr or stdout. It's really simple, if there's an error - write to stderr, if it's just info - stdout. For example, if I run your tool with wrong options, you might want to display an error, say Use --help for usage, this one belongs in stderr. If I run your tool with a valid option --help, please use stdout.

If it's your preference not to have long help strings near your code, don't. #define in a header file is perfectly fine, but it's really a personal preference. If I had to read the code of a command line tool I'd prefer its help string to be inside a file that handles options supplied by the user.

share|improve this answer
1  
That doesn't answer his question. –  Mavrik Feb 29 '12 at 8:39
    
Hm, what's up with the minus-ing? What for? –  devmiles.com Feb 29 '12 at 9:35
    
@Mavrik: the first paragraph does. –  haylem Feb 29 '12 at 9:45
add comment

I use the gnu getopts library. For an example with help, see this sample project, specifically the main method at the bottom of parser.y.

Since it is wrapped in curly braces, the vim editor I use can fold the lines together, and I don't even notice them when I don't need to.

share|improve this answer
add comment

If I use C or prefer not to depend on Boost libraries, then I stick with GNU getopt. Otherwise I prefer Boost Program Options which prints help automatically.

I also consider guessing the right option one of the best practices when it comes to options handling. I learned it from Git and now use the same in my projects. It basically uses Damerau–Levenshtein distance to print best matches if user enters some unknown command line option.

I wrote a little article about this that you can use as an example.

Hope it helps :)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.