We compare the Bash, Zsh, and fish shells

Shell Shopping

Article from Issue 245/2021
Author(s): , Author(s): , Author(s):

Don't let your familiarity with the Bash shell stop you from exploring other options. We take a look at a pair of alternatives that are easy to install and easy to use: Zsh and fish.

When you open a terminal window and start typing a text-based command, you are interacting with a command shell or command line interface (CLI). A shell is a program that acts as an interface to a command processor, the component that carries out commands by interacting with the underlying system.

Some of the command shells around today predate the birth of Linux and were originally used on classic Unix systems (see the box entitled "A Little History"). The most popular shell for Linux systems in the Bourne Again Shell, which is known universally as Bash [1]. Bash is the default for the terminal window on most systems, and Bash syntax is the norm for most popular discussions of Linux, including most of the articles in this magazine. But it isn't like you're stuck with it. Most distros include alternative shells in their package repositories, and it is easy to try out a different shell if you're interested.

A Little History

The first Unix shell was the Thompson shell, which was written by Unix creator Ken Thompson and appeared with the first version of Unix in 1971. The Bourne Shell followed eight years later in 1979 and was created by Stephen Bourne, who, like Thompson, worked for Bell Labs. The Bourne shell included several improvements over the Thompson shell and other early Unix shells, including better programming features and a more versatile means for defining the user environment.

At around the same time (late 1970s), an ambitious young Berkeley computer scientist named Bill Joy developed the C shell as part of his work on an early version of the BSD free Unix system. (Joy went on to cofound Sun Microsystems.) The goal of the C shell was to create a shell with a syntax that was more like the C programming language, to make the shell more intuitive for the many programmers who worked with Unix. The C shell was popular for many years, and an improved version of the C shell called tcsh is still a popular option today.

In 1983, Bell Labs rolled out another important shell option when the Korn shell (ksh) was announced at the USENIX technical convention. Korn shell, which was developed by David Korn, is backwards compatible with the Bourne shell but includes many features of the C shell.

The Bourne Again Shell (Bash) was the result of the Free Software Foundation's need to create a shell that was compatible with Bourne syntax but could be licensed with the GPL. Bash was originally written by Brian Fox. According to Wikipedia "Stallman and the Free Software Foundation (FSF) considered a free shell that could run existing shell scripts so strategic to a completely free system built from BSD and GNU code that this was one of the few projects they funded themselves, with Fox undertaking the work as an employee of FSF." Over time, Bash has picked up many useful features and has even adopted some features from the Korn shell and the C shell.

The small and fast Almquist shell, by Ken Almquist, also arrived in the late 1980s, as a clone of the System V Bourne shell, and it replaced the Bourne shell in several BSD versions. The Almquist shell is best remembered today as a forerunner to the Debian Almquist shell (Dash), which was developed in 1997 by Herbert Xu and which still exists today as a go-to non-interactive shell in several distros, including Debian and Ubuntu.

The Z shell (Zsh) first appeared in 1990 and was created by Paul Falstaff. Zsh is based on Bourne shell syntax but includes many extensions and improvements. The fish shell, which was initially released in 2005, does not fall neatly into the family tree of any of the previous shell variants. The creators of the fish shell wanted a practical and user-friendly shell option that was designed for the features of more modern systems and wasn't tied to the structures and assumptions of previous shells.

"Why switch?" you might be asking. If you're doing fine with Bash, there is no reason to change; however, many Linux users just like to experiment. And the fact is, the whole reason why all the different shells exist is because users saw something missing from the existing options and decided to innovate.

This article compares the Bash shell with a couple leading alternatives:

  • Z shell (Zsh) [2] – a Bourne shell derivative that borrows some features from C shell (csh) and the later tcsh.
  • Fish Shell [3] – a user-friendly shell that was designed for simplicity and convenience.

We'll end with a closer look at getting started with configuring the Z Shell.

What Do You Mean "Shell"?

Before diving deeply into comparisons, it is best to stop for a moment and consider that the term shell as it is used in this article can refer to any of three different components of the Linux environment:

  • Login shell – the shell that runs when you log onto the system. The login shell plays an important role in starting the user environment and defining custom settings
  • Interactive shell – the shell that interacts with a user entering commands at the command prompt
  • Non-interactive shell – a shell that executes the commands in non-interactive shell scripts

Note that these three shell types refer to a role, not to a specific tool. It is possible for the Bash shell or Zsh to serve in all three of these roles on a single system.

The following Bash command shows the shells that are currently installed on your system:

cat /etc/shells

If the shell you wish to activate isn't present on your system, install it using your system's package manger. For Ubuntu:

sudo apt install zsh

The path to the user's login shell is defined in the /etc/passwd file. You can change the setting interactively to another shell that has been previously installed on your system using the chsh command:

chsh -s bin/zsh

Alternatively, you can change the login shell using the usermod command:

usermod  --shell /bin/zsh user_name

Keep in mind that the files and settings that define your user environment are designed to work with your current login shell. If you change the login shell, be sure you know what you're doing, and be ready to fix something if it breaks.

For most modern desktop systems, the default interactive shell is defined in the configuration of the terminal emulator application. The steps for permanently changing the default depend on the terminal app. Several terminal tools let you define a profile, where you can specify a custom command to run when opening the session. Enter the name of the alternative shell in the box provided (Figure 1).

Figure 1: Configuring a terminal emulator for an alternative shell.

If you just want to experiment with using a different interactive shell from within a terminal session, in most cases, you can just enter the name of the shell at the command prompt:

$ zsh

The session should switch immediately to the new shell.

The non-interactive shell – the shell that runs a script – is defined in the interpreter directive (the shebang line) at the beginning of the script, which specifies the interpreter to use with the script:

#! /bin/sh

The sh name originally referred to the Bourne shell. Some modern systems use sh as a link to another shell. For instance, Ubuntu systems link sh to the Dash shell, which serves as the default non-interactive shell.

If you want your script to link to a different shell, you can just change the shell in the shebang line:

#! /bin/bash

But be aware that the script was probably written for a specific shell, and if you switch to a different shell, you'll probably need to adapt the script. The major shells have varying degrees of compatibility. A simple script written for bash might work in another Bourne-based shell, but there is typically no compelling reason to change. A more likely scenario would be that you would write a new script for an alternative shell and then use the interpreter directive to specify a shell that is not the default:

#! /bin/zsh

The interactive shell in your terminal emulator is the easiest way to experiment with different command shells. But remember, you can only activate a shell that has been previously installed on your system, so install the alternative shell first with your package manager.

Bash vs. Zsh

Most users who migrate from Bash to Zsh for interactive work report a smooth transition. Zsh, like Bash, is based on the Bourne shell, and many of the same commands work in both shells. A Linux user can sometimes sit down with a terminal app configured for Zsh and not even notice the difference.

The situation with scripts is a bit more complicated. Read on for a deeper dive into some of the details later in this article, but for now, it is interesting to note that Zsh comes with the ability to emulate other shells. Use the emulate command to specify which shell you would like Zsh to emulate.

emulate ksh

With no arguments, the emulate command shows the current emulation mode:


You can use emulation modes to get Zsh to behave like the Bourne, Korn, or C shell, although full compatibility is not guaranteed.

Zsh users believe Zsh has several advantages over Bash, including:

  • Better customization features
  • More advanced autocompletion and spell checking
  • A better collection of extensions and plugins

The popular and well respected Oh My Zsh project [4] provides a framework for extending Zsh, with a large collection of plugins, themes, and other helpers for bringing new features to Zsh. As you'll learn later in this article, Zsh also comes with a handy configuration menu that starts the first time you use the shell and helps you configure some important preferences related to autocompletion, command history, and more.

Zsh enthusiasts argue that Zsh does everything Bash does plus more, so why not just use Zsh? Bash holdouts maintain that the two shells do have some differences, especially for scripting, and with so many million scripts out in the world already written for Bash, why change? Many of the users who are accustomed to Bash in scripts also prefer to keep using it interactively in an effort to keep things simple and not have to contend with the details of another system.

It is worth mentioning, also, that, whereas Bash is licensed under the GPLv3 license, Zsh has an MIT-style license, a free but permissive, non-copyleft license similar to the BSD license. So if you prefer to use tools with copyleft protection, you're better off with Bash.

Bash vs. fish

Fish stands for Friendly Interactive Shell, and the emphasis is on "interactive." Even the fish developers recommend continuing to use Bash for as a non-interactive shell. For that matter, they point out that you could also write your scripts in any other languages you can reference from the shebang line, such as Python or Perl. Fish does, however, include some scripting features, allowing users to create their own functions in fish syntax to simplify tasks and add custom capabilities.

Fish was designed to address some of the weaknesses of the other shells, so it provides some benefits that aren't present in the other shells; however, this departure from tradition means that it is also the least compatible. The fish shell was envisioned as an interactive tool, and most of its benefits are at the command line. Fish provides sophisticated autocompletion that even accounts for command history in making suggestions. A useful tab completion feature lets you enter the first few letters of the command and press the tab key to see the possible options. Other shells offer tab completion, but the fish version uses actual information from the man pages for a more complete range of alternatives. Fish fans also like the automatic syntax highlighting. Incorrect parts of a command show up in red, allowing you to quickly see what needs correcting.

Enter the fish_config command at the fish command prompt to launch an extensive GUI interface that you can use for configuring and customizing fish settings (Figure 2).

Figure 2: Fish offers an extensive GUI interface for managing configuration settings.

But the best way to experience the fish shell is to try it for yourself. The fish project website includes a link to a web page where you can try the fish shell in a browser window (Figure 3).

Figure 3: Fish in a browser: Enter commands in the right pane while you work through the tutorial on the left.

Like Bash, fish comes with a copyleft GPL license.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Command Line: Fish

    The fish shell provides many features that rival the well-known Bash. We examine some highlights.

  • Fish Shell

    The Fish shell offers some user-friendly features for command line beginners.

  • Bash Builtins

    Even beginners can benefit from a greater understanding of the Bash shell’s many builtin commands.

  • Command Line

    A few basic tricks can liven up the command line and add a dash of color to your console.

  • Bash vs. Vista PowerShell

    Microsoft’s new PowerShell relies on .NET framework libraries and thus has access to a treasure trove of functions and objects. How does PowerShell measure up to traditional shells like Bash?

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More