bash vs zsh vs fish - Choosing the Right Shell for You

bash vs zsh vs fish - Choosing the Right Shell for You

Which Shell Should You Choose?

The answer depends on your use case.

  • bash — scripts, server administration, maximum portability
  • zsh — comfortable daily interactive use with strong bash compatibility (macOS default)
  • fish — best out-of-the-box completions and highlighting with zero configuration

If portability matters (scripts, shared servers), bash is the clear choice. If you want a great interactive experience without spending time on configuration, fish gets you there immediately. zsh sits in the middle — compatible with bash while offering a rich plugin ecosystem.

What is bash?

bash (Bourne Again Shell) is the default shell on nearly every Linux distribution and was macOS's default until 2019. It offers the highest POSIX compatibility and is the most portable option for shell scripting.

echo $BASH_VERSION
5.2.21(1)-release

Key characteristics:

  • Ships on virtually every Unix/Linux system by default
  • High POSIX sh compatibility
  • Minimal interactive features without configuration (no syntax highlighting, basic tab completion)
  • Enormous library of existing scripts and documentation

Use bash for any script you want to run reliably across different systems. #!/bin/bash is the most universal shebang line.

Bash's interactive experience can be improved by installing bash-completion, but it still trails zsh and fish in day-to-day usability.

What is zsh?

zsh (Z shell) is designed as an extended bash with enhanced interactive features. Apple switched macOS's default shell from bash to zsh in Catalina (2019), which significantly boosted its adoption.

echo $ZSH_VERSION
5.9

Key characteristics:

  • Runs most bash scripts without modification
  • Powerful built-in completion system
  • Rich ecosystem: Oh My Zsh, Powerlevel10k, hundreds of plugins
  • Extended glob patterns, spelling correction, right-side prompt (RPROMPT)

If you're migrating from bash, zsh is low-friction — most existing scripts run as-is. This is one of the main reasons it's recommended as a step up from bash.

Adding Oh My Zsh unlocks hundreds of plugins and themes, but be aware that a heavily configured setup can slow down shell startup times noticeably.

What is fish?

fish (Friendly Interactive Shell) is built around the principle of "works great out of the box." Syntax highlighting, autosuggestions, and man-page-based completions are active immediately after installation — no configuration needed.

echo $version
3.7.1

Key characteristics:

  • Real-time syntax highlighting as you type (valid commands in white, unrecognized commands in red)
  • History and man-page based autosuggestions enabled by default
  • Configuration at ~/.config/fish/config.fish
  • Not POSIX-compatible — uses its own unique syntax

Fish syntax is incompatible with bash/zsh. Standard patterns like VAR=value, if [ ... ], and export do not work in fish. Use fish for interactive sessions and keep bash for scripts that need to run elsewhere.

How do bash, zsh, and fish compare?

Feature bash zsh fish
Default on Linux distros macOS None
bash compatibility High Low
Tab completion Basic Powerful Best
Syntax highlighting Requires setup Requires setup Built-in
Autosuggestions None Plugin required Built-in
Configuration cost Low Medium–High Low
Script portability Best High Low
Plugin ecosystem Minimal Large (OMZ) fisher
POSIX compliance High High Low

When should you use each shell?

Server administration and DevOps

Use bash. Script portability and availability on remote systems are the priority. Most production servers won't have fish or zsh installed, and relying on a non-standard shell in automation scripts is a reliability risk.

#!/bin/bash
# Scripts meant to run across servers should use bash
set -euo pipefail
DEPLOY_DIR="/var/www/app"
echo "deploy started: ${DEPLOY_DIR}"

Daily interactive use (macOS or WSL)

zsh or fish. On macOS, zsh is already the default — adding Oh My Zsh or Powerlevel10k gives you a highly productive setup in minutes. Fish is the faster path if you want good completions and syntax highlighting with zero configuration.

# Switch default shell to zsh
chsh -s /usr/bin/zsh

# Switch default shell to fish (if installed)
chsh -s /usr/bin/fish

Learning Linux for the first time

Start with bash. Most tutorials, books, and online examples assume bash. Learning fish first creates a knowledge gap when you encounter bash-based scripts or documentation.

How do you check and change your shell?

Check your current shell

echo $SHELL
/bin/bash

You can also check the running process name:

ps $$
    PID TTY      STAT   TIME COMMAND
  12345 pts/0    Ss     0:00 -bash

List available shells on your system

cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/rbash
/usr/bin/rbash
/usr/bin/sh
/bin/dash
/usr/bin/dash
/usr/bin/zsh
/bin/zsh

Change your default shell

# Switch to zsh
chsh -s /usr/bin/zsh

# Switch to fish (if installed)
chsh -s /usr/bin/fish

chsh takes effect at the next login or terminal restart — it does not change your current session. Verify with echo $SHELL after restarting the terminal.

If fish is not installed, add it with:

# Ubuntu / Debian
sudo apt install fish

# macOS (Homebrew)
brew install fish

Common misconceptions

"zsh is faster than bash" — Startup speed depends on your configuration. A heavily-plugged Oh My Zsh setup is often slower than vanilla bash. Measure your zsh startup time with time zsh -i -c exit.

"fish can't be scripted" — Fish has its own scripting language, but it's incompatible with bash/POSIX sh. Fish scripting works well for fish-specific functions and completions; for portable automation, use bash.

"bash is outdated" — For interactive use, zsh and fish offer a better experience. For server automation, CI/CD pipelines, and portable scripts, bash's stability and ubiquity remain genuine strengths. Choose based on the task, not trends.

Next Reading