4 ms·
Command Line Interface Guidelines
- kazinator 3mo ago> A command is saying too little when it hangs for several minutes and the user starts to wonder if it’s broken. Nope. For debugging the program, it is nice to have some debug tracing option, but if it's not the program's specification to produce output, it should not produce any. If the program's specification is that it produces a certain output after a certain calculation, then it shall not produce any other output, even if that calculation takes three weeks. "cp -r from to" is supposed to be quiet until it's done or hits an error. It would be nice to have an agreed-upon protocol for progress reporting. For instance, imagine of we had file descriptor 3 as "stdprogress". Programs could dump specially formatted messages there which the parent job control shell could intercept and turn into a progress display (with multiple rows for pipeline elements and such). It's not bad; but fluff like this can't be in band with the output, or at least not by default.
- yjftsjthsd-h 3mo ago> It would be nice to have an agreed-upon protocol for progress reporting. For instance, imagine of we had file descriptor 3 as "stdprogress". Programs could dump specially formatted messages there which the parent job control shell could intercept and turn into a progress display (with multiple rows for pipeline elements and such). Different thing, but I am reminded of the BSDs having SIGINFO. > It's not bad; but fluff like this can't be in band with the output, or at least not by default. FWIW, I would describe stderr as being out of band. IIRC that's how e.g. pv works; `<file.img pv | dd of=/dev/foo` sends data along stdout while giving status info to the user since stderr isn't being piped.
- procflora 3mo agoIsn't this basically how more modern "chatty" CLIs use stderr? Put all the nice progress bars and emojis behind `if isatty(2)`? I thought so anyway, but I'll admit I've never actually looked at what npm, uv, etc. do.
- matheusmoreira 3mo agoThat's the right approach. Output goes to standard output, and user facing messages go to standard error. That way output can still be piped or redirected while the program talks to the user, and messages can also be suppressed by redirecting to the null device. I've always been annoyed by the fact file descriptor 2 is called the "error" stream. Should have been called the "user" stream.
- roundabout-host 3mo agoOr the "status" stream (you can still redirect it and it is useful sometimes).
- kazinator 3mo agoIf a tool unconditionally produces diagnostics on standard error, whether there is an exceptional situation or not, I consider that poor behavior, contrary to the quiet tool philosophy from Unix. Standard error is special output that the user should be able to somehow see (e.g. on a terminal) even if the regular output is redirected (as you note above). That doesn't mean standard error is above the quiet tool guideline.
- IgorPartola 3mo agoLots of programs report progress when you send SIGUSR1 or SIGUSR2.
- XYen0n 3mo agoAlthough not a standard protocol, `OSC 9;4` can be used to display a progress bar in the terminal emulator.
- cookiengineer 3mo ago> It would be nice to have an agreed-upon protocol for progress reporting. That was initially USR1 and USR2 as process signals, well, at least across binutils and coreutils. I just wish that UNIX architecture or POSIX would have been modernized since then, like with JSONL based process communication or similar things. In Go I usually end up building my own JSONL protocol to marshal/unmarshal states between long running processes. Wish that could've been a POSIX standard.
- mr_mitm 3mo agoMaybe the PowerShell folks were onto something when they implemented seven different output streams [1]. But then again most users are utterly confused by this and just dump everything to the information stream when they should be using the output stream, making their code near impossible to reuse in an idiomatic way. [1] https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_output_streams?view=powershell-7.6 https://learn.microsoft.com/en-us/powershell/module/microsof...
- hankbond 3mo ago> Whatever software you’re building, you can be absolutely certain that people will use it in ways you didn’t anticipate. Your software will become a part in a larger system—your only choice is over whether it will be a well-behaved part. good advice
- roundabout-host 3mo agoIt is, but then why does the "guide" contradict it tens of times?
- hankbond 3mo agoI'm in a charitable mood so I will just say that we rarely live up to our ideals.
- inetknght 3mo agoPrevious discussions: - (2024): https://news.ycombinator.com/item?id=39273932 https://news.ycombinator.com/item?id=39273932 - (2020): https://news.ycombinator.com/item?id=25304257 https://news.ycombinator.com/item?id=25304257
- eikenberry 3mo ago> Use a pager (e.g. less) if you are outputting a lot of text. If I wanted to use a pager I'd pipe the output to a pager, no pipe to pager means I want it all dumped to STDOUT. So annoying.
- keithnz 3mo ago100% - I want to use whatever pager I might prefer at the moment, this advice violates their core principle "you make programs that are modular enough to be recombined as needed"
- oneeyedpigeon 3mo agoI find it far more convenient for tools to take options to use a pager, rather than to having to manually type "| less" for every command that I want to behave nicely. Just behave nicely by default; if I want you to behave awkwardly, I'll let you know!
- chriswarbo 3mo agoDefine "nicely". For example, many pagers don't work well when stdin is line-buffered (they assume they'll see individual key presses as they happen) Pagers can also conflict with keys that the terminal emulator is using for a different purpose. This is especially annoying when the terminal emulator is using those keys for pager-like functionality in the first place! An example of both of these is Emacs `shell-mode`. (I personally set `PAGER=cat` in my Bash profile, which avoids most of these shenanigans)
- ventana 3mo agoThis is a common approach, CLI tools often use isatty [1] to check if the output fd is a TTY or not. Try running "git log" for example; if you have many commits, it will page through "less" or $PAGER only if it sees that you're on a real TTY; but if not, it will not. Try this: git log # PAGER undefined; uses less PAGER=/usr/bin/head git log # pages through head, you get 10 lines PAGER= git log # PAGER is empty; does not page git log | cat # output is not a TTY; does not page (also, notice that git uses colors if the output is going to a terminal, and does not if not) I don't think I was ever bothered by the automatic paging through "less". [1]: https://man7.org/linux/man-pages/man3/isatty.3.html https://man7.org/linux/man-pages/man3/isatty.3.html
- Grom_PE 3mo agoFor comfortable reading, I just had to figure out what on this webpage causes Chromium to drop subpixel rendering, and it's not this: html { -webkit-font-smoothing: antialiased; } it's this: #TableOfContents { backdrop-filter: blur(3px); } A panel that overlaps content only on narrow screens disables subpixel rendering for the entire text. Thanks Chromium. Not an issue on Firefox, btw.
- esalman 3mo agoI have used click/typer packages to build some python-based CLI programs. It's easy and user-friendly way to build, but the amount of time it takes for python to start the environment followed by the actual program to do anything is annoying.
- daitangio 3mo agoI use python click too, and it helps me to focus on design before implementing. I mean before asking AI to implement :)
- benrutter 3mo agoTangent, but anyone who's a fan of Typer, I'd massively recommend Cyclopts! It's essentially the same design, but takes advantage of some of the type features python introduced post Typer being written, to make things a little more consise. https://cyclopts.readthedocs.io/en/stable/ https://cyclopts.readthedocs.io/en/stable/
- atiedebee 3mo ago> The concise help text should only include: > - A description of what your program does. > - One or two example invocations. > - Descriptions of flags, unless there are lots of them. > - An instruction to pass the --help flag for more information. I disagree with this. The first 3 points should all unconditionally be in the man page of the program. In my ideal scenario, the jq short help message would omit everything after the "Usage" section except for the message to run the command with --help.
- oneeyedpigeon 3mo agoYup, I agree. There seems to have been a trend recently to output a LOT on `cmd` (poor), even more on `cmd --help` (unpaged too: bad), and to not have a man page (terrible!). Every program should have a man page, a bare command should give usage (ideally, a single line), and --help should give a decent short overview (ideally less than a screen height or, failing that, automatically paged).
- chriswarbo 3mo agoThe Nix commands have a decent approach: passing `--help` will invoke `man` on the relevant manual (sub-commands tend to have individual man pages).
- user3939382 3mo agoThis is my design as well, didn’t realize Nix arrived at it. Help renders the man page.
- jodrellblank 3mo agoIt's awful UX for a program to know that you used it wrong, to be able to print the help there and then, and instead to tell you off and instruct you to ask politely (with --help). People who think that's okay in CLI world hate that kind of uppity-C3PO-servant behaviour from an LLM. $ thing usage: -lscekm4urytmvjpq9i8u3o54ernymctpwi8eruymgv ah ah ah, <finger wag>, ask nicely for: --help $ thing -h ERROR! There is no option -h What could you possibly want? It's a mystery! What if -h was rm -rf / did you even think of that? Could have printed actual help here, Filling up your screen with text anyway and then you ask for --help and get five screens starting with "-a initialize line feed motor on electromechanical teletype output device from 1964" and on and on with options nobody uses mixed with the same priority amongst parameters everyone uses. This is yet another area where GUI programs on Windows 98[1] were better than today's Linux state of the art: pressing F1 opening a separate window with HTML-based help with contents, colours, fonts, text styles, hyperlinks, tables, pictures, an index, a search, is so vastly superior that it's unbelievable[2] that here we are in 2026 and Linux world is still infighting over whether a pager is a sign of weakness and low status, or whether showing help by default is a sign of a low quality programmer, for a problem that was completely solved during the Clinton Administration! (And presumably solved in a similar way earlier by classic MacOS, earlier by Amiga OS, and earlier at Xerox PARC). Having a single output stream and trying to do everything on it is just bad design. Having the program guess what you want, or a toggle to change between working and being informative, or an environment variable to trigger the toggle, are downstream problems that can never please everybody, to avoid facing the bad design and dealing with it. [1] https://en.wikipedia.org/wiki/Microsoft_Compiled_HTML_Help https://en.wikipedia.org/wiki/Microsoft_Compiled_HTML_Help [2] it's completely believable
- ljwolf 3mo agoWhy is this high x-height serif-based typography taking over SF aesthetics now?
- user3939382 3mo agoCheck out Apple Garamond. What’s old is new.
- jklowden 3mo agoGeez, what a lot of vague self-contradictory self-regarding opinionated advice. Is terminal a world of “pure information’ or “a mess”? Both, it seems. Don’t dump “pages and pages of debug” text? Check. But do use boldface fonts “in a terminal independent way” and “try” to provide man pages. But because “some people” don’t know about them and “some platforms” don’t support them, provide help text by default. Those “some” by the way are one: Windows. Do please enlighten us on the terminal-independent font control system that includes CMD.EXE. How much is too much? Their showcase examples are more than 25 lines, more than the default size of a terminal window. The authors don’t give much weight to context, to the ability to look back on over the history of the interactive session. No, much better to splat the screen with 50 lines the user didn’t request, because helpful. Oh, and don’t write a filter like cat(1). How the system is supposed to distinguish between reading from standard input and reading from standard input by mistake, they don’t say. Just quit and print a help message. I have different advice: please don’t help. Please be quiet. Don’t suggest, don’t guess, dont offer, don’t assume. Just do. Do what the user said. If he wants something else, he’ll say so in time. If you want —help to do something useful because you think your user is too dense to find the manual (condescension much?) then invoke it for him. Just maybe put a hint somewhere to press “q” to quit. Virtually all the “help” I get on the command line is unasked-for and unwanted and unhelpful. If I fat-finger “ls”, I don’t need a suggestion to install lsof. The very last thing I want is 50 lines of noise obscuring what I was looking at before you so helpfully interrupted.
- roundabout-host 3mo agoDo they really not use the following patterns, which I find quite common? cat > file cat >> file But really, if you feel that you're waiting too long, can't you just ^C? Isn't it better to teach people rather than making the programs "helpful" (i.e. sometimes helpful, but more often annoying)?
- kps 3mo agoColour addendum: If the user hasn't configured anything, don't use a colour other than red without checking whether the terminal has a light or dark background. Don't hardcode colours.
- roundabout-host 3mo agoIf you use the 14 standard colours (the plain old colours minus black and white), shouldn't they be set to something readable in the terminal emulator configuration? Of course, the 256-colour mode should not be used. And how do you check the background?
- kps 3mo agoNo, not simultaneously usable as foreground and background colours. For instance, on a light background, the default yellow is a good ‘highlighter’ background. If yellow is reconfigured to be dark enough to be usable as a foreground colour (i.e. brown), it's no longer usable as a background. You can't have both, and you can't assume the user has picked one or the other. > And how do you check the background? OSC 11
- roundabout-host 3mo agoDisplay output on success, but keep it brief. Traditionally, when nothing is wrong, UNIX commands display no output to the user. This makes sense when they’re being used in scripts, but can make commands appear to be hanging or broken when used by humans. For example, cp will not print anything, even if it takes a long time. It starts with talking about no indication of success, then switches to no indication of progress. I think they are pretty different. Also, what kind of "responsive" font sizing does this website have?