Best Practices for Printing Usage/Help (–help)

code-qualityprogramming practices

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.

Best Answer

Inspire yourself from your target platform's internals

Have a look at the BSD's 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.

Related Topic