Which shell to use? bash, zsh, fish, something else?
I have been using bash
as a shell for as long as I remember and added prompt customization for almost as long as I remember.
I felt the urge to revisit this and asked around what the favorite shell was and I investigated a bit.
Context
macOS has decided to deprecate bash
in favor of zsh
.
It has something to do with licensing and being fed up with maintaining a decade old bash
version themselves.
It was not a blocker for me as Homebrew lets you install an up to date bash
version anyways but I’ve been increasingly dissatisfied.
My prompt uses Powerline, a Python based prompt that I found a bit brittle.
I had to fix it every new minor version of Python coming due to path changes.
And I was in dread of making it fall into working condition every time I wanted to change something.
Onto finding my new home shell.
One big caveat before that, I am perfectly happy writing my scripts in bash
and won’t change my programming language, so this post is focused on the shell and prompt aspect of the problem.
And the winner is
I got seduced by Zsh + oh-my-zsh for its plugin ecosystem and attachable auto suggestion features and am using Starship to customize the prompt. But that’s just me. Read more to know which one is right for you.
Bash and Starship
If you want minimal changes and a zero fiddling prompt solution, bash
+ Starship is for you.
Considering bash
remains the most deployed, you can’t go wrong compatibility wise.
The first good surprise I’ve found is Starship. Starship is a cross-shell prompt written in Rust (from the “everything is better in Rust” movement). I really love it for a few very simple things.
It’s fast, well I guess you can +1 Rust for that one.
Everything is already integrated into one simple executable, so no need to maintain plugins, figure out why the interpreter no longer works etc.
It is shell agnostic, so any investment you make on it will work equally for bash
zsh
or fish
. To my point, I can now start in bash
or zsh
and have a similar prompt experience.
And finally, it focuses on the prompt and nothing else.
Fish
The extreme to bash
is Fish
.
For people that wants something that is entirely integrated, just works and has some nice UI niceties, fish shell is the way to go.
I have not tested it thoroughly myself but I have heard of quite a few people really happy with it, in particular the proposed line completion from history. No additional install, it just works with great auto suggestions. From that angle, Fish is unbeatable.
Be aware of one key aspect though, Fish is the furthest away from other shell syntaxes (especially bash
), so you might encounter some incompatibilities.
Once such example is the inability for JBang to let Java files be executable.
Another is that setting of environment variable does not follow the classical export KEY=VALUE
model.
For these reasons, I left this choice out as I did not want a radical rewriting of my .bashrc
file.
Zsh
Zsh is for people wanting an interesting mix of a good compatibility with Bash
and an ecosystem of plugins with a reasonable installation process.
Zsh is often combined with Oh My Zsh a plugin system and collection of plugins that enhance the shell. Oh my zsh covers several aspects.
It’s a plugin system to integrate multiple Zsh scripts. This is quite handy as instead of customizing one’s own .zshrc
(.bashrc
) with custom code, you simply import plugins. It makes for a more maintainable system.
It’s a theme provider in particular to the prompt, and let people customize the prompt ad nauseam. I am not personally making use of it as I delegate that task to Starship.
It’s a collection of curated plugins for a wide variety of tools (git, maven, kubernetes etc). Each of these plugins offer one of the following features: add to the prompt, add common aliases to shorten commands, add auto completion capabilities, add tool integrations. Tool integrations are things like ssh-agent, vi mode, nicer history navigation.
Special Zsh plugin mentions
I might have gone heavy on the plugin side but I have enabled the following so far:
- git — auto completion and some aliases
- osx
- autojump — integration with autojump, a must have to navigate directories
- colored-man-pages — who does not like colors
- copydir — copy the path of the current folder in the system clipboard
- copyfile — same for the file passed as parameter
- docker — for its completion
- dotenv — sources the
.env
file of the directory - git-auto-fetch — fetch the remotes of the git repo you are in
- git-escape-magic — some tool to work around some Zsh glob issue with
HEAD^
and friends - httpie — completion
- oc — completion for OpenShift command
- ssh-agent — ssh-agent integration
- vi-mode — because there is only one sane keybinding
- zsh-sdkman — installed in custom, sdkman completion
I also use zsh-autosuggestions which is a Fish-like autosuggestions for zsh
Honorable mentions
ctrl+r
lets you search history but is not the most usable user experience. McFly is a replacement that works for all shells and offers a more user friendly interface.
While we talked shells, some people recommended some terminal emulators:
- lots of people re using iTerm2 (macOS).
- some recommended kitty which is a fast GPU accelerated terminal emulator
- others mentioned Alacritty which is also OpenGL accelerated and claims to be the fastest. One interesting philosophy is that it does not support tabs nor splits as tmux or screen do it already. I’m personally giving it a spin.
Ready to jump?
You can start and experiment by starting the shell from the prompt
# enter zsh
$ zsh
# come back to my default shell
$ exit
When ready for the big jump, if your shell is present in /etc/shells
, go and run chsh -s /bin/zsh
or whatever is your final choice.
Do you ahve tips or experience, let’s share them on Twitter. I’m here at @emmanuelbernard.
Comments