I’ve been a fish shell user for more than a decade. I cannot for the love of me understand this fixation on zshell. Why is it more popular than fish?
The author suggests writting autocompletion, installing a plugin dependent on an external program. If you wrote a manpage (which is also suggested) you get those three things for free with fish. Out of the box.
zsh is mostly bash compatible and fish is not really. I don’t want to learn a new shell language right now. The few times I need to write something bashy interactively (not a script I can call bash on) it normally works inside zsh.
Having tried both, I think fish is nicer but I couldn’t use it. I already had muscle memory for bourne shell syntax and switching to fish made that stop working - I was constantly trying to type things that did not work, and then having to go manually look up the fish equivalent.
I would go so far as to say that there are a lot of places where fish is gratuitously different from sh, in that the syntax is different but not meaningfully better, just different.
Off topic: I’m a full-time fish user now, and I had no problem with it, although I’m rather used to using multiple languages at the same time. I contributed new completions for fish—something I never got to do with bash. However, these days I also avoid shell scripting like a plague, so I may be starting to forget how to write in Bourne shell already, but it doesn’t really bother me anymore. ;)
On topic: I agree that CLI confusion with TUI is a grave sin. Borders and other decorations have no place in CLIs at all. All CLI tools must be capable of detecting non-interactive use and automatically stoppind all output except actual data (and should provide a way to switch to that mode by hand). In a TUI, of course, anything goes, although accessibility considerations still exist there.
From what I remember, completion scripts are one of the places where fish is vastly easier to understand than bash or zsh.
However, these days I also avoid shell scripting like a plague
It wasn’t that I was trying to write shell scripts, it’s that at that point in my life I was doing a lot of ad-hoc for X in $(y); do ... done and xyz | while read X; do ... done one-off one-liners. For scripts worth reusing I had Python and liked it.
This comment reflects my experience and opinions on fish as well. In summary: in theory, I like it more than zsh, but in practice its uniqueness gets in the way too much.
I’ve personally found fzf-tab to be miles better than Fish tab-completion, especially alongside “z” or others like it (z.lua, zoxide), fzf history search, etc. Being able to fuzzy-search directories and tab-completions with the same interface, often with preview windows, is an absolute game-changer.
I just used fzf-tab as an example of the benefit of adding simple, short, busybox-style help text alongside a more comprehensive manpage. Manpage explanations of CLI flags tend to be too long for ideal shell-completion; I’d be less likely to get the most relevant fuzzy matches first.
I updated the article to mention --dry-run. Diff. (the article looks a bit different since that commit since I split the recommendations into subsections)
I don’t think non-destructive should usually be the default; if I run delete-thing foo, I expect foo to be deleted. This is less of an issue if you follow the advice to make functionality obvious from the command line invocation.
One time I had accidentally created a directory named ~ somewhere, so standing in the parent directory I issued rm -rf ~ :)
So I learned the hard way about tilde expansion, which isn’t exactly the fault of rm or anything but myself, but maybe wiping your home directory could be a bit harder.
But it also would be really annoying if rm asked you every time, so I don’t know what a good solution is. Maybe it’s actually to teach people about a different tool that moves things to “trash” instead of rm, as they are getting started.
But even with such a tool, you probably wouldn’t want to send ~ to the trash.
I have a request: please could you elaborate on point 6 in the first list, about common formats for --help output? I’m just not sure what good practice looks like here and could do with a specific example. Do you mean like using an off the shelf library like Python’s argparse that automatically generates the --help message in a structured way from the tables which specify what options should exist?
I’ve been a fish shell user for more than a decade. I cannot for the love of me understand this fixation on zshell. Why is it more popular than fish?
The author suggests writting autocompletion, installing a plugin dependent on an external program. If you wrote a manpage (which is also suggested) you get those three things for free with fish. Out of the box.
zsh is mostly bash compatible and fish is not really. I don’t want to learn a new shell language right now. The few times I need to write something bashy interactively (not a script I can call bash on) it normally works inside zsh.
Having tried both, I think fish is nicer but I couldn’t use it. I already had muscle memory for bourne shell syntax and switching to fish made that stop working - I was constantly trying to type things that did not work, and then having to go manually look up the fish equivalent.
I would go so far as to say that there are a lot of places where fish is gratuitously different from sh, in that the syntax is different but not meaningfully better, just different.
Off topic: I’m a full-time fish user now, and I had no problem with it, although I’m rather used to using multiple languages at the same time. I contributed new completions for fish—something I never got to do with bash. However, these days I also avoid shell scripting like a plague, so I may be starting to forget how to write in Bourne shell already, but it doesn’t really bother me anymore. ;)
On topic: I agree that CLI confusion with TUI is a grave sin. Borders and other decorations have no place in CLIs at all. All CLI tools must be capable of detecting non-interactive use and automatically stoppind all output except actual data (and should provide a way to switch to that mode by hand). In a TUI, of course, anything goes, although accessibility considerations still exist there.
From what I remember, completion scripts are one of the places where fish is vastly easier to understand than bash or zsh.
It wasn’t that I was trying to write shell scripts, it’s that at that point in my life I was doing a lot of ad-hoc
for X in $(y); do ... done
andxyz | while read X; do ... done
one-off one-liners. For scripts worth reusing I had Python and liked it.This comment reflects my experience and opinions on fish as well. In summary: in theory, I like it more than zsh, but in practice its uniqueness gets in the way too much.
Bash compatibility really seems to be the primary reason. Unix refuses to die, and so does Bash (I blame POSIX sh).
I’ve personally found fzf-tab to be miles better than Fish tab-completion, especially alongside “z” or others like it (z.lua, zoxide), fzf history search, etc. Being able to fuzzy-search directories and tab-completions with the same interface, often with preview windows, is an absolute game-changer.
I just used fzf-tab as an example of the benefit of adding simple, short, busybox-style help text alongside a more comprehensive manpage. Manpage explanations of CLI flags tend to be too long for ideal shell-completion; I’d be less likely to get the most relevant fuzzy matches first.
Started as a response to another article which was discussed here earlier this week: https://lobste.rs/s/av7f4o/ux_patterns_for_cli_tools
Oh, and if anyone has more ideas to add, please share them! I plan on updating the article indefinitely.
I like it when CLI tools make me feel safe experimenting.
It would also be really interesting to see more localisation in CLI tools. They could support multiple languages at once, easily, unlike GUIs.
tool commit
andtool skrásetja
.alias
but would be nice.)In general I feel like there’s a lot of untapped potential in CLI tools.
I updated the article to mention
--dry-run
. Diff. (the article looks a bit different since that commit since I split the recommendations into subsections)I don’t think non-destructive should usually be the default; if I run
delete-thing foo
, I expectfoo
to be deleted. This is less of an issue if you follow the advice to make functionality obvious from the command line invocation.Exceptions exist. I’ll have to think about this.
I think
rm
is pretty obvious.One time I had accidentally created a directory named
~
somewhere, so standing in the parent directory I issuedrm -rf ~
:)So I learned the hard way about tilde expansion, which isn’t exactly the fault of
rm
or anything but myself, but maybe wiping your home directory could be a bit harder.But it also would be really annoying if
rm
asked you every time, so I don’t know what a good solution is. Maybe it’s actually to teach people about a different tool that moves things to “trash” instead ofrm
, as they are getting started.But even with such a tool, you probably wouldn’t want to send
~
to the trash.Edit:
undo
would be nice to have in more tools.I have a request: please could you elaborate on point 6 in the first list, about common formats for
--help
output? I’m just not sure what good practice looks like here and could do with a specific example. Do you mean like using an off the shelf library like Python’sargparse
that automatically generates the--help
message in a structured way from the tables which specify what options should exist?Thanks for the feedback; I just cited Busybox as a good example. Diff.
Not nearly as verbose as a full man page, but good enough for a quick reference.
Thank you
I noticed I cannot search this story by using
Search
on the menu bar.Are you referring to browser built-in page search? If so, what browser/OS are you using, and does it work without browser extensions?