A reason why Unix programs sometimes support '-?' for help

I recently read Clayton Craft's -h --help -help help --? -? ???? ( via ). In part of it, Craft mentions '--? / -?' as help options, and says about them:

???? I have no idea where these came from, but my guess is that they are migrants from the wild west Windows-land, where I assume the shell won't try to expand ? into anything. [...]

I think there's a different and far more Unixy explanation, and it's our friend getopt(3) , and the Bourne shell getopts equivalent. Both getopt(3) and getopts return errors, such as unrecognized options, through what we could call in-band signalling , instead of using an additional return value (both C and normal Bourne shell don't handle multiple return values very easily). Classical getopt(3) normally returns the latest option character for you to parse; when it hits an option character you don't accept, it instead returns a special marker character. This marker character is '?'. Shell getopts follows the same approach (although in the shell case, you might match on any otherwise un-handled option character ).

( GNU getopt_long() has its own conventions for this return value .)

As a result, Unix programs using getopt (or shell scripts using getopts) can't have '-?' as a valid command line option for anything meaningful, because there would be no way to tell a real '-?' apart from an error. As a consequence of this, it's almost always safe to run a program as 'program -?'; no matter how large and weird its collection of command line option letters is (ls is famous for using almost all of them, including '-h'), it won't be using '-?' and so running it that way is a generally safe way to get some sort of usage message (and an error).

Once people start running 'program -?' to get a usage message, programs themselves have an incentive to make '-?' print a longer help message, and perhaps to list it in getopt() or getopts as a valid option, so that people no longer get "invalid option -- '?'" messages or the like when they're doing it deliberately.

(Since getopt() itself generates the 'invalid option' message, people will still get this for genuinely invalid command line options; listing '?' as a valid option only affects whether you get the message for 'program -?'.)

This gives you the situation where some programs accept '-?' for help (and probably then accept '--?' because why not), and some sources of advice suggest running programs as 'program -?' to at least get a basic usage message to remind you and perhaps some help too.

PS: In normal Unix shells, there's no problem using '-?' as a command line argument even though '?' is a filename wildcard character. Normally, non-matching wildcard characters are passed through intact as argument characters. Tcsh behaves differently, but if you use tcsh as your shell that's up to you.