Try Out Fish For Your Command Line Shell
Not into heavily configuring your terminal? Right out of the box, the fish shell will transform your CLI experience.
Abbreviations are now available in zsh. Check out my plugin zsh-abbr!
In the article Configure Zsh Options & Plugins for Productivity in macOS's Default Shell I walked through customizing zsh's interactive shell to add what I consider key features. (An "interactive shell" is the shell as experienced in a terminal, as opposed to when writing shell scripts.) In the end we had nice history management, a shorthand for
cd, the ability to jump to a directory we were in several
cds back, command completion with an interactive menu, inline suggestions, completions for various programs, an intuitive way to filter history, syntax highlighting in the terminal, and an informative prompt. In short, the result was interactive shell that felt smart and helped us find and do things more quickly without any need to learn additional tools.
But getting zsh there took significant configuration. There are other approaches — Oh My Zsh, for example, is an enormous collection of zsh configurations you install in one go. Oh My Zsh did a lot to popularize zsh as a shell for people who wanted a great interactive shell experience and snazzy prompt. But it includes more customization and extension than most people need or will even discover, and as each of those confers a (usually small) performance hit some long-term users end up switching to a more paired-down configuration — that's what the previous post is.
There's a much easier way: switching to fish. fish is a shell that puts the command line experience first. Out of the box it comes with almost everything in my recommended zsh setup circa 2019, and a lot more. In fact, many of the plugins in that zsh setup are inspired by built-in fish features, and they don't always live up to the original.
zsh is still a wonderful shell. Its comprehensive builtins and elegant syntax make all kinds of cool programming tight. But if you spend much time running commands in a terminal, try fish there.
fish is available for macOS, Linux, BSD, Windows, and as source. It's probably distributed in whatever way you expect packages for your system to be distributed in. There are links on the fish homepage (note: the homepage might be too cute for its own good. If you're looking for a starting guide, jump straight to the Tutorial).
On macOS, you can install fish with Homebrew:
brew install fish
and then make it available to the system by adding
/usr/local/bin/fish to your
Installing fish doesn't commit you to using it. You can switch an individual session to fish by running
Any other open sessions (i.e. other open terminal windows) and any other sessions you start won't be affected. If you want to get out of your fish session and switch it to bash or zsh or anything else just run
If you're coming from bash, fish will automatically import your history (and here's the procedure for merging bash history into an existing fish history). If you're coming from zsh and want to migrate your history over, there's rsalmei/zsh-history-to-fish (and here's the procedure for merging zsh history into an existing fish history).
If you decide to make fish your default shell, run
chsh -s /usr/local/bin/fish
Comparing fish and zsh interactive shells
Here's a rundown of the features in my recommended zsh setup circa 2019. Tl;dr: fish does it out of the box. All zsh configuration instructions are given in Configure zsh Options & Plugins for Productivity in macOS's Default Shell.
Other great fish features
fish has a bunch of things going for it that other common shells don't. Here are a few that jump out:
- Startup and each new prompt are fast! The fish maintainers have invested time in making the interactive shell experience load quickly.
- History search, with globbing! Run
history search "my command"to search for instances of "my command" in your history. Or run
history search "my*gl?b"to search for instances of "my*gl?b".
- 🆕 Abbreviations are now available in zsh. Check out my plugin zsh-abbr! Abbreviations! They're similar to standard aliases, but they expand inline. If you have the abbreviation "gc" for "git commit",
gco<space></space>will immediately be replaced with
gco<enter></enter>will be replaced with
git commitand the command will be run. This means you can save keystrokes without forgetting the full command, and your history will be more meaningful. Adding abbreviations is simple: to create that "gc"/"git commit" abbreviation, run
abbr gc git commit. More options are available — run
abbr --helpto see them.
- Beginner-friendly documentation.
- Discussion and contribution happen on GitHub, making the bar for entry low (zsh is mailing list-based; bash has a Savane tracker; ksh is on GitHub but currently the few maintainers have their hands full with modernizing the codebase)
- Web UI for essential configurations. fish really doesn't want you to have to be a shell scripter to fine tune your interactive shell. Run
fish_configto open a browser window where you can
- visualize and choose between various color schemes (I control this in my terminal app though, not with fish),
- visualize and choose between prompts,
- see all the functions built into the shell,
- see all global variables and their values,
- see your history and delete any records,
- see all configured key bindings (ie keyboard shortcuts),
- and see your abbreviations and delete any of them.
I still enjoy digging through the zsh docs and spending weekends fiddling with the configuration. If that isn't you, check out fish. It's like like switching from dollar store foam headphones to nice noise-cancelling ones, except free: you do nothing, and suddenly things you didn't know could be better are.