💾 Archived View for dmerej.info › blog › 0097-crafting-command-line-outputs.gmi captured on 2022-01-08 at 13:43:27. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-11-30)
-=-=-=-=-=-=-
2019, Mar 25 - Dimitri Merejkowsky License: CC By 4.0
I've used many command line tools. It always makes me feel happy when I come across a tool that has a nice, usable and friendly output. I always try to make those I create or maintain as good as possible in this regard.
Along the way, I've learned a few tricks I'd like to share with you.
When designing command line output, start with the *contents*, not the style. In other words, think about *what* to print before thinking about *how* to print it - this is helpful in a lot of other situations.
The absolute minimum your command line tool needs are *good error messages*. Pay attention to those - good error messages can go a long way in helping your users and may even save you from having to answer a bunch of bug reports!
A good error message should:
Bad example:
Could not open cfg file. ENOENT 2
Good example:
Error while reading config file (~/.config/foo.cfg) Error was: No such file or directory Please make sure the file exists and try again
Speaking of error messages, note that your can choose to write text to *two* different channels (often called `stdout` and `stderr` for short). Use `stderr` for error messages and error messages only. People sometimes need to hide "normal" messages from your tool, but they'll need to know about those errors!
Things to know about colors:
https://bixense.com/clicolors/[1]).
1: https://bixense.com/clicolors/
If your comman-line tool does some lengthy work, you should output *something* to your users so that they know your program is not stuck.
The best possible progress indicator contains:
`wget` does that really well. Your favorite language probably has one or two ready-to-use libraries for this.
If you can't achieve the full progress bar, as a lightweight alternative you can just display a counter: (`1/10`, `2/10`, etc.). If you do so, please make sure the user knows *what is being counted* !
We already saw that people maybe running your tool without a terminal attached. In this case, you should skip displaying progress bars and the like.
Also, try to remove things that are only useful when debugging (or don't display them by default).
This includes the time taken to perform a given action (unless it's useful to the end-user, like if you are writing a test runner for instance). Also, don't forget that users can and will prefix their command line with `time` to get precise results if they need to.
A good technique to remove noise is to completely erase the last line before writing a new one.
Here's how to do it in Python:
size = shutil.get_terminal_size() # get the current size of the terminal print(first_message, end="\r") do_something() print(" " * size.columns, end="\r") # fill up the line with blanks # so that lines don't overlap print(second_message)
Of course, this only works if the user does not need to know about the whole suite of messages!
End-to-end tests are a great way to tweak the output without having to do a bunch of setup by hand, *and* check the error messages look good.
Well, that's all I've got today. Please keep those tips in mind when creating your own command line tool, and if you find a program that does not adhere to these rules, feel free to send patches. Until next time!
----