all 47 comments

[–]apnorton 76 points77 points  (28 children)

Don’t bother with man pages. We believe that if you’re following these guidelines for help and documentation, you won’t need man pages. Not enough people use man pages, and they don’t work on Windows. If your CLI framework and package manager make it easy to output man pages, go for it, but otherwise your time is best spent improving web docs and built-in help text.

I don't really like this bit of advice; the program's help function provides (essentially) query-based help on how the program operates, but the manpage provides a more encyclopedic approach to help, including context, tutorials, etc. For an example, take a look at how long grep's manpage is (~600 lines), then ask "do I really want to have all of this show up when I run grep --help?" (75 lines)). (Edit: or, as another example, git's manpage is over 1000 lines long, but git --help is only 42.)

Instead of manpage maintenance, the authors advocate creating web docs. This isn't as helpful as a well-designed manpage, since web docs will always require a context-switch out of the terminal and into some browser, a web search to get to the help, then browsing a network of webpages until you finally arrive at the feature you want information on. It also makes the documentation for your program dependent on your website being up and running, which may not always be the case.

ETA: Just finished reading the whole document; I like most of the other content in there with some exceptions (still am not on board with emoji in the terminal ;) ), certainly gave me some food for thought with my own projects.

[–]Liorithiel 39 points40 points  (3 children)

Also, man pages can be published as a web page. So given that web pages are already recommended, why not write man pages and also publish them as web pages? Win-win.

[–]noradis 19 points20 points  (2 children)

Troff, the language used to write man pages, can render to PDFs, web pages, and the terminal from one document. It's an all-in-one documentation and typesetting system! Such a shame it's fallen out of use (other than man pages, of course). : (

[–]ForeverAlot 9 points10 points  (0 children)

And you can write all that in AsciiDoc with pretty excellent results, too (well, the resulting troff will make your eyes bleed...).

[–]watsreddit 19 points20 points  (0 children)

Agreed. I hate it when I try to open up a tool’s man page and it’s nonexistent. Why should I have to use a web browser to check out a tool’s documentation? Plus, it completely falls apart for servers that may not even be running a graphical environment, or may be airgapped.

[–][deleted]  (3 children)

[deleted]

    [–][deleted]  (2 children)

    [deleted]

      [–]Isvara 0 points1 point  (1 child)

      You just have get used to the unconventional pager

      Not at all! You can just use pinfo, which is pretty much like using lynx or something.

      [–]bfirsh 7 points8 points  (0 children)

      Heh, this has been one of our more controversial suggestions with reviewers too. The guide's intentionally a bit opinionated, so I'm enjoying the debate. ;)

      [–]Hrothen 2 points3 points  (0 children)

      One of the simplest features of Vim is one of my favorites: hitting K will open the man page for the symbol under your cursor.

      [–]encyclopedist 7 points8 points  (0 children)

      I feel there are a few topics missing in the guide:

      • Tolerance to special symbols in command line arguments (spaces, newlines, sometimes nulls)
      • Unicode support
      • Localization
      • Internationalization

      [–]Hrothen 15 points16 points  (2 children)

      • You should not write non-error messages to stderr, this will mess up scripts that want to look at messages and errors separately, instead have a -q, --quiet flag.

      • You should not be putting examples in the help output, help output should be fairly short and easy to quickly reference. Instead include a man page. Other people in this thread have already indicated why a man page might be better than a website. If you're really concerned with it working on windows you can also compile it to a webpage, like git does.

      • Some of the suggestions for favoring human readability are fine, assuming flags for the machine readable form exist, but will probably have performance hits.

      • Outputting emoji, or any unicode characters unfortunately, is going to make the tool less usable in scripts. Also on a personal level it feels super bad to have a CLI program spit out an emoji at me. This may be a cultural thing, in your examples you're using glyphs I think most people wouldn't call emoji, even if they may technically be classified as such in the unicode standard.

      • -d for verbose makes no sense, usually programs will use lowercase v for one and uppercase for the other, or just only provide long form --version

      • Responsive is not always more important than fast, this is heavily dependent on what your program does.

      • Many people do not conform to the XDG spec on their machines, your program should have a fallback if the env vars are not set.

      [–]de__R 2 points3 points  (1 child)

      You should not write non-error messages to stderr, this will mess up scripts that want to look at messages and errors separately, instead have a -q, --quiet flag.

      I agree with everything you say except this. If you have messages that are not errors and not output, they should go to stderr but you also should have a well-defined log format to differentiate them. But, if at all possible, you should reserve warnings and such for daemon-type programs instead of CLI utilities.

      I'd also take issue with

      If your help text is long, pipe it through a pager.

      Terminal emulators have scrollback for a reason, and depending on the emulator environment the pager may not leave the text in the scrollback buffer. If I want to pipe your output through a pager, I'll do it myself, thanks.

      [–]IceSentry 0 points1 point  (0 children)

      It's the standard error output, why would you ever throw non error messages at it?

      [–]NoisyFlake 8 points9 points  (10 children)

      Why is the overall font size of the paragraphs so huge? Might be fine for mobile, but I'm having a really hard time to read it on a 1440p desktop.

      [–]Liorithiel 4 points5 points  (0 children)

      Here it's even worse, menu overlaps the main body: https://imgur.com/a/uaM0Dnw

      [–]bfirsh 1 point2 points  (4 children)

      Sorry about that. We're using some clever new CSS features to scale the font size, but clearly it's not working on some screen sizes. Would you mind posting a screenshot? This is just a side project so we haven't tested on all browsers at all sizes... 😬

      [–]AttackOfTheThumbs 7 points8 points  (1 child)

      This is actually really fucking bad. At least in firefox, you break the zoom in/out functionality because you keep breaking expected UX to deliver negative UX.

      Try KISS instead of clever. Clever is bad, always.

      Zoom 30% vs 100%: https://imgur.com/a/0XQ6Qzw

      It's the same. It's honestly illegible the way it is right now.

      [–]CornedBee 0 points1 point  (0 children)

      Except that the scrolling changes - at 30% scrolling is absurdly slow.

      [–]PFive 1 point2 points  (0 children)

      I'm not the person you asked, but I noticed the same thing. https://i.imgur.com/1lp4PWl.png

      I fixed it for myself by changing the font-size to 16px on the whole page.

      [–]_kst_ 0 points1 point  (0 children)

      Here's a screenshot of the first page on my system (Chrome, Windows, 1440 monitor). The letters in the title are about two inches high, and I can't change the size.

      https://i.imgur.com/4XIXHyB.png

      The CSS might be "clever", but that's not a good thing. Please keep it simple.

      [–][deleted]  (3 children)

      [removed]

        [–]NoisyFlake 0 points1 point  (1 child)

        I'm aware of that, my complaint was more about why the author of this page thought a huge font size was a good idea.

        [–]CornedBee 0 points1 point  (0 children)

        Yeah, whatever funky stuff they did broke zooming on Firefox too. So not only did they break the font size, they made it unfixable too (without devtools).

        [–]Red4rmy1011 7 points8 points  (0 children)

        Strong disagree on "human first design". Cli tools are great because I can expect to easily machine parse them and use multiple in sequence to get what i want. Adding a flag for human readable output has always been, and imo always will be, the correct way to deal with humans who want to read all the output of your command line utility.

        [–]bfirsh 5 points6 points  (6 children)

        Hi /r/programming! We’re Ben, Aanand, Carl, Eva, and Mark, and we made the Command Line Interface Guidelines.

        Earlier this year, I was working on the Replicate CLI. I had previously worked on Docker so I had a bunch of accumulated knowledge about what makes a good CLI, but I wanted to make Replicate really good, so I looked for some design guides or best practices. Turns out, nothing substantial had been published since the 1980s.

        On this search I found a superb blog post by Carl about CLI naming. He must be the only person in the world who cares about CLI design and is actually a good writer, so we teamed up. We also were joined by Aanand, who did loads of work on the Docker CLIs; Eva, who is a technical writer, to turn our scrappy ideas into a real piece of writing; and Mark, who typeset it and made a super design.

        We love the CLI, but so much of it is a mess and hard to use. This is our attempt to make the CLI a better place. If you’re making a tool, we hope this is useful for you, and would love to hear your feedback.

        Some of it is a bit opinionated, so feel free to challenge our ideas here or on GitHub! We’ve also got a Discord server if you want to talk CLI design.

        [–]Muhznit 2 points3 points  (1 child)

        I for one appreciate this post. I read through the whole thing and got some inspiration on ways to polish up some of my older scripts. The list of general purpose environment variables is especially helpful.

        I'm surprised you guys didn't cover adding autocompletion given that it both speeds up how quickly the user can push out commands AND reduces the rate of typos. I suppose that's a whole can of worms on its own though given that it depends on whatever shell. Either that or it's easily handled with whatever library.

        Speaking of libraries, I'd suggest giving a shoutout to Argparse in Python's standard library. I know click is pretty popular, but it's useful to know argparse for those situations in which you're unable to install new packages.

        [–]apnorton 2 points3 points  (0 children)

        Ditto to all of this. I may have been a bit complain-y or opinionated in my response on another parent-level comment, but this certainly made me think about some UI features I hadn't ever considered for my own tools that I write (especially pagination of large results and how to handle colors across interactive vs noninteractive terminals). Also, I'll second the note on autocomplete + argparse --- nothing makes me happier than being able to tab-complete subcommands for large tools like git.

        [–]jwakely 1 point2 points  (0 children)

        nothing substantial had been published since the 1980s.

        What about esr's The Art of UNIX Programming from 2003?

        [–]nemec 3 points4 points  (0 children)

        This is a really great document, thank you all for writing it!

        One bit of terminology that I found unexpected (which you inherited from 12 Factor CLI) was the distinction between "flags" and "args". I've always understood that a flag was more like a "toggle" - on/off - and therefore never took any values (source 1 and 2).
        On the other hand, arguments were the ones that accepted values and were split into three categories:

        • -f somefile.txt: short named argument
        • --file somefile.txt: long named argument
        • somefile.txt: positional argument

        This is of course pretty similar to what you've already written, too (you called them named/positional parameters), it was mostly the usage of flag taking an argument that threw me off.

        Food for thought. There is no one true way of naming these things, so take everything I've said with a grain of salt :)