top | item 29329607

Ask HN: What are the best and worst command-line interfaces you have used?

33 points| de_keyboard | 4 years ago

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?

83 comments

order
[+] urxvtcd|4 years ago|reply
Nearly everything that packs or unpacks stuff. tar, gunzip, and else. I can never remember if they are going to unpack everything into a subdirectory or spill everything into my home, and conversely I never know if after zipping there's gonna be a directory inside or not. Luckily dtrx and atool do the thing you want most of the time.

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.

[+] doteka|4 years ago|reply
Long ago someone taught me this memory trick for tar: imagine an angry German stereotype saying “eXtract Ze Vucking File”, thus -xzvf. No idea what it stands for but it does what I need most of the time.
[+] DanielVZ|4 years ago|reply
Yeah, extractors/compressors are so bad i ended up hacking my own interface over the common utilities in python (i called it tzar because it's tar, zip, anything really).
[+] jquast|4 years ago|reply
May I suggest to use “zipinfo” or “tar -t” to check the contents of the archive before extracting
[+] jasode|4 years ago|reply
The ImageMagick utility mogrify.

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...

[+] captn3m0|4 years ago|reply
> mogrify - resize an image, blur, crop, despeckle, dither, draw on, flip, join, re-sample, and much more. Mogrify overwrites the original image file, whereas, convert(1) writes to a different image file.

The whole reason for mogrify's existence is that it overwrites the original image file.

[+] cozzyd|4 years ago|reply
well, use convert instead. It's the only difference...
[+] bduffany|4 years ago|reply
Not the worst (I think `tar` and `unzip` probably take the cake) but `find` is pretty atrocious IMO. The order in which you specify certain flags like `-maxdepth` relative to other option flags matters (not just relative to plain arguments, but relative to other option flags starting with `-`).
[+] BoxOfRain|4 years ago|reply
`find` is definitely one of my least favourite among the traditional Unix tools in terms of interface. `dd` is also a little weird with its syntax but at least I rarely have to use `dd`.
[+] gglitch|4 years ago|reply
Find is fine. Grep is fine. I do wish they took arguments in the same order.
[+] btschaegg|4 years ago|reply
Good:

For interactive shell scripting:

- AWK. Old enough to be part of the POSIX standard and yet considerably more awesome than almost any other UNIX command.

- socat for any kind of network/socket testing stuff.

- sponge and entr just for their genuine usefulness with minimal interface.

For interactive use:

- SSH. I mean, obviously. It's also astounding how well OpenSSH integrates into the whole *NIX TTY landscape. You can use it for years and still learn neat things about it.

- Vim. Yes, it's obscure to learn, but once you do, boy do you get a lot out of it. Also: Since `:terminal`, working on one-off scripts has become considerably more awesome.

- htop and btop++ are good examples of TUIs for interactive use.

- tig is also quite cool for many git interactions (especially partial staging).

- lnav for log analysis tasks.

For batch jobs you set up and trigger as needed:

- Beets (see: beets.io). It's impressive how streamlined it works once you've set it up.

Bad:

- Pretty much anything Microsoft. I really don't understand how it's possible to consistently produce bad CLI programs for such a long time.

- As a prime example, have a look at `sc sdshow` and `sc sdset`.

Edit: Perhaps to clarify about the sc SDDL commands:

If you look them up, you won't find much "bad" in their documentation. Because nothing about the SDDL syntax they are built on is documented. The best you can do is scrape together what you can from third-party blogposts with a perceived signal:noise ratio of .000001.

And SDDL in itself is phenomenally badly designed. And, of course, this being Microsoft, the tool isn't designed to be used together with other programs.

[+] rwmj|4 years ago|reply
My niggle is with commands that cannot be composed, ie. consumed by other tools or shell scripts or built into pipelines. There are lots of small things that break composition: Not exiting with a non-zero code on error, sending error messages to stdout, not producing output that can be easily parsed by another command. Too many commands suffer from one of these problems, unfortunately.
[+] frou_dh|4 years ago|reply
One that's unfortunately quite common is unconditionally outputting ANSI colour escape sequences even when the output isn't the terminal.
[+] qsort|4 years ago|reply
Honestly that's the drawback of unix-ish interfaces. Don't get me wrong, text first is usually a sane default, but there is also value in an interface like Powershell, where you would write your program as a Cmdlet that returns an object-like response.
[+] sergiotapia|4 years ago|reply
worst is git by far.

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.

[+] MontyCarloHall|4 years ago|reply
The worst thing about git is how commands are inconsistently overloaded.

`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.

[+] lcall|4 years ago|reply
For me, the fact that there are so many who really like git makes it worth recommending a cheat-sheet (or put up with it) for the rest, just to be compatible and have fewer tools to deal/learn with overall, but yes there are reasons some like svn, hg, or fossil. But there are also "got" (currently on openbsd at least) and other convenience tools.

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.

[+] linspace|4 years ago|reply
Some day I will burn a day of my life to learn it inside out and be done with it. Meanwhile I use magit.

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?

[+] zombietfk|4 years ago|reply
100% agree with this. The nomenclature of the commands always felt too similar for different things to me, i.e. reset vs revert, checkout vs fetch vs pull. Feel like there could be much more descriptive and distinct names.
[+] kwertyoowiyop|4 years ago|reply
If someone comments “git is fine once you get to know it” I might reach through the internet and slap them.
[+] amznbyebyebye|4 years ago|reply
Agree it is one of the most unintuitive cli I have ever used. If it’s really just manipulating a DAG, I wonder if a rewrite is possible with this in mind.
[+] codemusings|4 years ago|reply
Worst: sqlplus by Oracle. No autocomplete, no backspace, no history function. It's like nobody ever inside Oracle ever had to use this craptastic piece of software to accomplish anything.

EDIT: Oops backspace works. Might have been a combination of putty and sqlplus. Nevermind.

[+] MontyCarloHall|4 years ago|reply
A lot of people forget that the default shells of many *nix systems through at least the mid 90s did not support any of these. No line editing, no interactive history (primitive !-based history doesn’t count), no completion.

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.

[+] visiblink|4 years ago|reply
The best: an old CD player called Workbone on Slackware. It made great use of the number keys for pause/play/ff/rw/eject.

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.

[+] notacoward|4 years ago|reply
Many of the worst ones I've used have been embedded in physical devices - ethernet or fibre channel switches, disk arrays or controllers, etc. I've been around long enough that I don't expect every CLI in the universe to have things like history, command line editing, or autocomplete, so that's OK. On the other hand, many of these interfaces are wildly inconsistent and that bugs me. Some commands are object-verb and some are verb-object. Some are abbreviated, some are verbose. One command produces an identifier in format X, but the next command consumes it in format Y so you can't even use your terminal's copy/paste function. Excessive modality is another common problem in these interfaces. Which sub-sub-sub-mode was the command I needed in, again? Can't know without actually entering that mode, and then the next related thing you have to do is in a completely different part of the tree. Using such interfaces directly can be painful, and automating them is often inordinately difficult too.
[+] BlackLotus89|4 years ago|reply
Why is nobody hating on megacli? It's the only tool I use where I actually need a wrapper script. There are other horrible command line experiences, but nothing anyone here listed I would describe as horrible...
[+] notacoward|4 years ago|reply
Megacli is definitely one of the examples I was thinking of when I said many of the worst CLIs are embedded into physical devices. What a piece of trash.
[+] runjake|4 years ago|reply
The Windows Resource Kit binaries come to mind. They were distributed together in the same ZIP, but:

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.

[+] adonovan|4 years ago|reply
ps(1). It has two incompatible theories of options from the two parent tools that spawned it, both equally horrible. ps -e f is not the same as ps -ef or ps ef. Also, implementations vary wildly across platforms.
[+] blakesterz|4 years ago|reply
Does something simple like htop count? I believe there's a bunch of other good stuff that uses ncurses as well.
[+] Cicero22|4 years ago|reply
I detest the MikroTik cli. I suppose the cli itself isn't terrible, but the fact that it's coupled with the mikrotik scripting language leaves a very bad, nearly rotten, taste in my mouth.
[+] stackedinserter|4 years ago|reply
To me, openssl and nmap are the worst.

Kubectl is among the best: commands make sense and have internal logic, interface is discoverable, output is configurable and supports different formats.

[+] sam_lowry_|4 years ago|reply
Nah. Kubectl is so verbose that it reminds me of typing xslt in my younger years.

k9s would save us all from carpal syndrome, but it's a curses UI, not a cli.

[+] urxvtcd|4 years ago|reply
openssl reminded me of gpg, wow, this one is horrible, and manuals don't help at all.
[+] BoxOfRain|4 years ago|reply
I'm rather fond of pgcli at the moment, though I haven't used it long enough to get a brilliant feel for it yet.
[+] speedgoose|4 years ago|reply
I find it very easy to remember many terrible command line user interfaces, they are already mentioned in the discussion, but very hard to name a single great one.

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.

[+] bjourne|4 years ago|reply
Maybe cli's aren't good for interacting with computers? Heresy I know. ;)
[+] amznbyebyebye|4 years ago|reply
R dplyr is one of the best interface I have ever seen for manipulating data. I think one of Hadley’s biggest contribution to the world of data science. It feels like my brain can breathe out dplyr code
[+] zaphirplane|4 years ago|reply
Anything with the Command —global-flags subcommand -subflags command -flags parameters

Git does this but is workable because it’s 2 levels and you don’t need to specify various flags defaults are usually ok