I was a zsh (and oh-my-zsh) user for many years. And before zsh Iâve used bash for quite a while. Bash was okay, and with a few âadd-onsâ (oh-my-zsh + a couple plugins) zsh was really good.
But I think if you routinely shopping in only one place, you may be missing out on some amazing deals in other places. So, it worth checking whatâs sold in a different supermarket every once in a while. And so I decided to have a look at the alternatives.
Most of the shells did offer different syntax and a few features like Tab-completion, history, arrow-up/down search through previous commands, but nothing that would make me want to switch. Some shells did offer something different, sometimes way too different and I wasnât adventurous enough for them :)
Fish
Fish was a love from first sight. Right outside of the box it offered elegant syntax and very useful features such as:
- syntax highlighting
- history-based completion autosuggestions
- <Tab> completions
- man-pages based arguments completion
- functions, commands, aliases, and even abbreviations completions
- elegant syntax (better than
bash, in my opinion)
Fish stands for Friendly interactive shell, and it really tries to live by itâs name.
zsh
zsh can do more than fish can do with plugins. Plugins list for zsh is just massive. Some of the plugins are inspired by fishâs built-in functions.
But Kirill, if itâs more powerful, why did you switch then?
Plugins are good and bad. On one hand you can add functionality, on the other hand some of those plugins are slowing zsh down. Such plugins as zsh-users/zsh-syntax-highlighting can cause quite significant slowdowns. When I was using zsh zdharma-continuum/fast-syntax-highlighting wasnât available, so I wonât speculate if itâs better. The point stands still, - you add plugins and can experience performance issues. A few milliseconds here and there add up.
Fish, on the other hand, have almost all I need without add-ons. Iâve already listed some of the main things fish does right out of the box, and they are quite fast!
Other shells
I ruled out shells like tcsh, ksh, and dash, - the look kinda old-fashioned, and the donât offer anything to be excited about. Should I say anything about sh (Bourne shell) here? I guess, I wonât :) Same goes for the successor of sh, bash (Bourn-again Shell)
Worth checking out
nushell looked very interesting (and still is). It strives displaying information in a better (usually table) form. Also allows querying data better (i.e. you can do something like ps | where cpu > 20 with it). But I guess ability to display information in a table form and ability to query information using SQL-ish syntax are not the selling point for me. I guess because Iâm quite good at using find (and fd), grep (and rg), awk and other tools. The shell is super-interesting though, maybe I will give it a try one day.
xonsh is a python-powered shell. Itâs a superset of python, so all the python code just works. Also has a pretty long list of plugins (called âxontribsâ), so itâs kinda like if zsh was written in python.
nsh is something that I could give a go. I can clearly see fishâs influence, but I also see itâs a little immature and not very well maintained (not sure if it will not share the same fate with rush).
elvish looks neat, I might check it out one day.
Why shell speed matters for me?
Shell performance probably doesnât matter all that much for the most of the users. If all you do on your shell is running a few commands every once in a while, thatâs fine, - 20-100ms delays here and there are tolerable. I personally use shell A LOT, and I can definitely tell when shell performance affecting my own performance.
When Iâve tried fish for the first time, I was blown away by the features I can get without installing any extras, and how fast and fluid it was.
Fishy Caveats
When bash script has no fish version
Some scripts are only written in bash and zsh is a superset of bash and as such can execute any bash script.
As such, there is no ânativeâ way of running something like nvm for instance. There is a workaround though. There are execution wrappers such as bax or bass which allow to run bash scripts in fish. So you can still have your nvm available on the command line with a little fish function:
function nvm if test -f /usr/local/opt/nvm/nvm.sh bax source /usr/local/opt/nvm/nvm.sh --no-use ';' nvm $argv end if test -f ~/.nvm/nvm.sh bax source ~/.nvm/nvm.sh --no-use ';' nvm $argv endendBTW, Iâve found fnm to be a better (in terms of performance) replacement for nvm.
But most of the time people writing popular software will implement a fish version. For instance, fzf has key-bindings.fish, navi has navi.plugin.fish, phpbrew offers phpbrew.fish.
The point is, this caveat is not really a huge problem.
$_, $?, $$ etc
The special variables which youâd use in bash/zsh arenât available in fish. I can live without them :)
Rewriting bash scripts to fish
I donât have an awful lot of scripts, and those which I did have were quite easy to rewrite.