Ask HN: What are the best and worst command-line interfaces you have used?
I am interested in learning what makes a great (or terrible) command-line interface.
What are some of the best and worst command-line interfaces you have used?
What are some of the best and worst command-line interfaces you have used?
84 comments
[ 3.3 ms ] story [ 221 ms ] threadEDIT: Oops backspace works. Might have been a combination of putty and sqlplus. Nevermind.
Occasionally I’ll still encounter an environment that only has a minimalist implementation of sh (e.g. some busybox builds) and be totally stymied. It amazes me how much people accomplished on old *nix systems with such abysmal usability.
i'm used to it now but when I was learning, "what the fuck did `git reset --hard` do? where is --soft? Is there a no-flag version? What the fuck did I leave mercurial for. God damn I miss svn."
I still kind of miss Mercurial and TortoiseHG.
`git reset` both unstages files (opposite of `git add`, straightforward enough) but also can move the current HEAD pointer to an arbitrary commit. You’d think it could then also discard unstaged changes, but nope, that’s `git checkout -- …`, which incidentally has nothing to do with `git checkout`’s other functionality of switching branches.
There are so many other examples of this. `git rebase` can not only rebase but also combine and reorder commits via `rebase -i`, which seems totally unrelated to rebasing. `git branch` and `git checkout` have overlapping but also distinct functionality. I could go on for hours.
Mercurial was much better IMO but people argued about performance, because, you know, the CPU is the bottleneck when I merge code. How much time has been wasted navigating Stack Overflow?
I also found myself making myself a "gh" script to make finding/opening the right git manpage easier/quicker.
I always thought the UI of "git commit --interactive" was at a sweet spot of being both helpful and efficient, once I got familiar with it the first time. It is easier to remember than command-line options. Related UI details in another comment in this page.
By default (without specifying extra command-line options) it overwrites the input files. [1]
In decades of computer use, that is the only command line tool that tricked me into destroying my data because I didn't realize it works differently from all the other tools I use that don't do that.
Usually, a command line utility with less options specified is relatively "safe" and you have to add extra syntax to make it "unsafe".
It was definitely a violation of: https://en.wikipedia.org/wiki/Principle_of_least_astonishmen...
EDIT reply to: >The whole reason for mogrify's existence is that it overwrites the original image file.
Sure, I understand that but many other destructive tools will have safety UI features such as creating ".bak" backup files. That's what many other command line tools do including image utilities. So something like mogrify could have been designed with hypothetical syntax as "mogrify -nobackups". The principle is to type extra syntax to make it more dangerous while still accomplishing the (observable) goal of changing the original files.
[1] https://superuser.com/questions/1575004/imagemagick-how-to-a...
The whole reason for mogrify's existence is that it overwrites the original image file.
Imagine having the command “sedd” aliased to `sed -i`. It would be a usability nightmare.
Then it should not exist. To save one "rm", doesn't look like a good idea to me.
It definitely should.
This becomed critical when you are doing batch processing large amount of images in a cloud instance or somewhere else where disk space is a constraint.
I have used mogrify and similar custom solution when trying to batch-edit gigabytes of images while cleaning data for Computer Vision training.
Kubectl is among the best: commands make sense and have internal logic, interface is discoverable, output is configurable and supports different formats.
k9s would save us all from carpal syndrome, but it's a curses UI, not a cli.
The only pity is that mosh breaks compatibility with earlier versions once in a while.
From the time I was a teen I think I remember that mount was difficult to use, and mounting a CD image required passing some arcane options, though maybe I just didn't know how to use it (on the other hand I didn't know how to use Daemon Tools either, and it just worked).
I don't have a problem with git though. I don't think it's the command-line interface that's hostile, it's git itself if you don't know what you're doing. After taking some time to learn it I actually enjoy solving difficult problems with git.
edit: i do hope that is correct without checking :-)
- UNIX options, which may be grouped and must be preceded by a dash.
- BSD options, which may be grouped and must not be used with a dash.
- GNU long options, which are preceded by two dashes.
Reference: https://man7.org/linux/man-pages/man1/ps.1.html
[0]: https://theunarchiver.com/command-line
You can leave off the 'z' if it's a tar without compression. If it's compressed, the extension is usually tgz, tar.Z, bz2, or something else other than tar.
You can leave off the 'v' if you don't want to see a list of which files are being added or extracted.
ˋfd` is a worthy successor of ˋfind` though.
this could apply to literally anything. my time is not infinite.
The worst: I used to work with an awful custom-built industrial computer.
You had to enter the 10-character alphanumeric codes of 98 rail cars into a command-line interface that didn't permit backspacing. One mistake. Car 97. Do it all again.
1. They used differing return values for success and failures. Sometimes, a 0 was a success, sometimes 1 was a success, and sometimes only 4 was a failure, but everything else was a success.
2. They used different command-line switch formats. Some utilities used a hyphen, others used a forward slash.
If you mean TUI wise as in curses, nearly all of them.
Command line parameters however, there are so many examples. Tar, unrar and unzip take the cake, all in the same category of tools. "unrar x" whatever it is, I always have to look it up. dd because of the way its parameters are specified: dd if=/dev/zero of=foo.bar bs=4096 count=1024 . It's all historical and I can live with it, but many of them at least have the saving grace that they have excellent manpages or you've used them so often it becomes second nature.
There should be a special place in hell for tools that combine short and long style command line options with a single dash. Like "foo -b a -r -baz 123" with "-baz" being a single option, because I will automatically add an extra dash there out of habit.
Coworkers discovering ncurses or some library around it tend to go on a TUI frenzy for a while, and it inevitably ends up being some convoluted mess nobody wants to use. I'll admit there's a few indispensable curses based tools, for instance top (and some variants along that line), but they're far and few in between. At most dialog comes to mind for dealing with prompts for end users, but I personally abhor it in anything but a setup or installation context.
Those very same coworkers also make tools with indecipherable command line options, often because they don't know the language they're working in has a standardized option parser library or module.
> best
I don't remember which tool it was, it could be "crm" (for failover, think like heartbeat and pacemaker) but I might be mistaken. It's been years since I've used it. The command line had options like so:
tool [options] section action resource_src resource_tgt
But the best part was, if you just started the tool without any options, it'd drop you into a pseudo-shell. It'd show you a blank prompt ending in ">". If you then typed "section" you'd end up with a "section>" prompt.
I remember for what I was doing with it, it felt really intuitive. At any point I could type "help section" and it'd list the available actions for that section, together with short example.
I've forgotten the real syntax, but you'd have commands like:
tool node status
tool node standby servername
tool service stop dns
tool service migrate dns secondary
If you were in the pseudo-shell, you could do:
$ service
service$ migrate dns secondary
service$ up
$ node
node$ status
node$ exit
Similarly, I always thought the UI of "git commit --interactive" was at a sweet spot of being both helpful and efficient, once I got used to it.
(All the above inspired the UI of the knowledge manager I wrote/provide at http://onemodel.org -- AGPL, I use daily and rely on it for many things, currently requires user to perform postgresql installation & upgrades; hoping to move to sqlite someday, when health allows. But most people, especially non-keyboard-oriented people, probably wouln't like its UI. It is perfect for me: very efficient/effective and everything you need to know is on-screen.)
And vim & tmux are things of beauty, after the initial investment (ongoing, for vim).
Maybe a good command line user interface is one you don't notice nor remember. It just work smoothly. So I will start with cat.
https://tailordev.github.io/Watson/
https://brew.sh/
I do like anything that's a nice well-structured representation of an API though – things like the AWS CLI are pretty good in practice, IMO.