Table of Contents
Overview
In the Linux world, the terminal is usually controlled by a shell. Bash, Zsh, and Fish are three popular interactive shells, each with its own philosophy and feature set. Bash is the long‑time default on many distributions, Zsh is a powerful and highly customizable alternative, and Fish focuses on ease of use without configuration.
This chapter focuses on how they differ in practice, what they feel like to use, and when you might want to choose one over the others. It does not teach the full syntax of any shell, and it does not replace the general explanation of what a shell is.
Bash: The Traditional Default
Bash, short for “Bourne Again SHell,” is the most widely used shell on Linux. Many beginner tutorials assume you are using Bash, and a large number of scripts you find online are written for it.
Bash aims for compatibility with the older Bourne shell sh, while adding useful features such as command history, basic completion, and programmable prompts. When you open a terminal on many distributions, you are placed in a Bash shell by default, which makes it a natural starting point for beginners.
A key practical consequence of Bash’s popularity is that system scripts and many admin tools expect Bourne‑style syntax. This does not mean you must always interact in Bash, but it does mean that if you learn basic scripting later, the syntax will probably be Bash compatible.
Bash is also conservative in design. It gives you completion, history, aliases, and other quality‑of‑life improvements, but often requires manual configuration to make these features feel truly modern. Distributions sometimes ship with helpful defaults, but many users install extra frameworks or modify their ~/.bashrc file to improve prompts, add colored output, or configure smarter tab completion.
Zsh: Powerful and Extensible
Zsh, or “Z shell,” is another POSIX‑style shell that is largely compatible with Bash syntax while offering more advanced interactive features. Some distributions choose Zsh as a default interactive shell for user accounts, especially where a more featureful command‑line experience is desired out of the box.
Zsh is known for powerful and flexible completion. It can complete not only file names, but also options and arguments for many programs, such as git subcommands or ssh hostnames. With the right configuration, completions can be context‑aware, colorful, and menu driven. Zsh also supports more advanced globbing patterns for matching files, which users often exploit for complex file operations.
Another factor that distinguishes Zsh is the ecosystem of configuration frameworks. Tools like Oh My Zsh or similar projects provide ready‑made themes, plugins, and default settings that significantly change the look and feel of the shell. These frameworks are not part of Zsh itself, but in practice they are one of the main reasons users switch. They add features such as informative prompts that show git branch status, suggestions, and convenient aliases, without requiring the user to write all the configuration manually.
Because Zsh syntax is close to Bash, simple scripts you run interactively or from files often work the same. However, highly advanced features and options can differ between the two. For an absolute beginner, this means you can usually move between Bash and Zsh without relearning the basics of command entry, but you should be aware that not every script written for Zsh will run unmodified in Bash.
Fish: Friendly Interactive Shell
Fish, short for “Friendly Interactive SHell,” takes a different approach. Its goal is not to be another strict POSIX‑compatible sh clone, but to provide a modern, user‑friendly command line with minimal configuration.
The most visible feature of Fish is its interactive assistance. As you type, Fish can show you autosuggestions in a lighter color derived from your history and known commands. If the suggestion is correct, you can accept it with a single key press. Fish also provides syntax highlighting for commands as you type them. Valid commands and paths appear differently from invalid ones, which gives immediate feedback before you press Enter.
Fish comes with sensible default key bindings, helpful tab completion, and a structured, readable configuration style. It does not rely on huge external frameworks for a basic pleasant experience. Many users who choose Fish do so because they want features like autosuggestions and colorized feedback without spending time tuning multiple configuration files.
The main trade‑off is that Fish syntax is intentionally different from POSIX shells. Control structures, variables, and other scripting constructs use a distinct, more regular syntax. This makes it less suitable for writing scripts that must run under sh or Bash. In many environments, system scripts and automation still assume a POSIX shell, so Fish is often used as an interactive shell only, while scripts are written in Bash or sh.
For a beginner, Fish can feel very approachable. Autocomplete hints and suggestions can help you remember commands and options. The downside is that if you later copy and paste Fish‑style script fragments into places that expect Bash syntax, they will not work.
Interactive Features Compared
Although all three shells let you run commands, they differ in how they assist you moment to moment at the prompt.
Bash provides history, basic completion, and a customizable prompt, but many advanced features depend on extra configuration. Out of the box, completion may be limited to file names and simple cases, and suggestions for options or subcommands can be less rich than in the other shells unless you add completion scripts.
Zsh is strong in interactive convenience. It supports sophisticated completion behaviors, such as listing options for many known programs, offering multiple matches in a selectable menu, and handling more complex patterns when matching file paths. With plugins, it can add per‑command hints, better history search, and quick navigation shortcuts.
Fish focuses on making all this help immediate and visible. It highlights syntax as you type and shows autosuggestions based on your previous commands and existing paths or commands. Instead of requiring external frameworks, Fish ships these capabilities as part of its core design, so new users see them right away.
In everyday use, the difference feels like this. In Bash, you run commands and gradually learn about features like history search. In Zsh, you often enhance the shell with plugins and themes to get a highly tailored environment. In Fish, you get a guided experience with clear feedback, at the cost of nonstandard syntax.
Scripting Considerations
The three shells differ importantly in how suitable they are for scripting that is meant to be portable across systems.
Bash is widely available and closely aligned with the traditional sh model. Many system scripts and tutorials are written directly for Bash or for sh. When a script starts with a shebang line like:
#!/bin/bashit explicitly requests Bash, which is commonly present on Linux systems. Because of this, Bash is a practical language for simple automation tasks that you want to share with other Linux users.
Zsh can also be used for scripting, but its strongest role is as an interactive shell. While it can run many Bash scripts unchanged, the reverse is not always true if you use Zsh‑specific features. On systems where Zsh is not installed by default, scripts that depend on it require extra packages, which reduces portability. For a personal environment, using Zsh‑specific scripting is fully acceptable, but shared scripts often stick with Bash.
Fish is designed primarily for interactive use. Its scripting language is not compatible with POSIX shell syntax. A shebang line for a Fish script would look like:
#!/usr/bin/env fishSuch scripts run only where Fish is installed. System initialization scripts, distribution utilities, and many admin scripts avoid this, because they must run in base environments where Fish is not guaranteed to exist. For a beginner, this means that learning Fish does not directly translate into writing widely compatible shell scripts.
For scripts that must run on many Linux systems, prefer POSIX‑style shells such as sh or Bash. Fish scripts are not a drop‑in replacement for Bash scripts.
Configuration and Customization
Configuration also differs between Bash, Zsh, and Fish, both in file names and in philosophy.
Bash typically reads configuration from files like ~/.bashrc for interactive shells and ~/.bash_profile or ~/.profile for login shells. Within these files you can define aliases, functions, environment variables, and prompt settings. Customization is flexible but can become complex as you add more features.
Zsh uses its own configuration files, commonly ~/.zshrc for interactive settings. Frameworks like Oh My Zsh encourage you to edit central configuration files that load themes and plugins. This makes it easy to enable a large set of features, but also means that configuration is often layered through multiple files. For users who enjoy tweaking, this is a strength; for users who want simplicity, it can feel like extra complexity.
Fish stores configuration in ~/.config/fish/ with files like config.fish. Its syntax is more uniform and often easier to read. Fish also provides built‑in commands to manage functions and variables, and some graphical tools in certain environments. The design encourages a more structured configuration model, where separate functions and snippets live in dedicated files.
From a beginner’s perspective, Bash and Zsh feel similar conceptually, since they share many conventions inherited from earlier shells. Fish feels different, with a more guided and self‑describing configuration system but at the cost of being less aligned with traditional shell practices.
Compatibility and Portability
Compatibility is important when you move between different Linux systems or distributions.
Bash is almost always present on Linux, and often on other Unix‑like systems. Scripts written for Bash or basic POSIX shell tend to run in many places, so knowledge of Bash syntax is transferable. When documentation for command line tools assumes a shell, it usually assumes something Bash compatible.
Zsh is growing in popularity but is not guaranteed on minimal systems. As a login shell for interactive use, it is easy to install when you control the environment, such as on your own workstation or a development server. On constrained systems or containers, only sh or Bash may be installed.
Fish has to be explicitly installed in most distributions and is rarely used for system scripts. If you often connect to many different servers that you do not administer, you will usually land in Bash or a similar shell. On your own machine, you can set Fish as your default shell, but on remote machines you may still prefer to know how to work comfortably in Bash.
Because Bash syntax lines up more closely with other POSIX shells, learning it gives you a foundation you can use in broader Unix environments. Zsh builds on this foundation while adding interactive niceties. Fish gives you a pleasant daily interface but does not replace the need for POSIX shell knowledge if you plan to write portable scripts.
Choosing Between Bash, Zsh, and Fish
When you decide which shell to use day to day, there are a few practical questions to consider.
If you are just starting and want the least surprise when following tutorials, Bash is often the simplest choice. It matches most examples you will see, and it is installed and configured by default on many systems. Learning Bash first also makes it easier to understand system scripts and job automation you may encounter later.
If you want a more powerful and customizable interactive environment, and you are willing to install additional tools or frameworks, Zsh is appealing. It combines compatibility with richer completion, themes, and plugins. Many users who spend a lot of time in the terminal choose Zsh for this reason.
If your main concern is an easy and helpful interactive experience, and you accept that scripts written in this shell will not be portable, Fish is attractive. The autosuggestions and immediate visual feedback can be especially helpful while you are still building muscle memory for commands.
You are not limited to a single shell forever. You can keep Bash for scripting and system work and use Zsh or Fish interactively. You can also switch back and forth or experiment in separate terminals. Over time, you will discover which trade‑offs best match your way of working at the command line.