Should You Switch? zsh and fish vs bash

Should You Switch? zsh and fish vs bash

Should you switch from bash to zsh or fish?

Conclusion: If you only want a nicer interactive experience, switching is worth it. But keep bash for servers and scripts for safety.

The decision comes down to what you want to optimize.

  • Nicer interactive use (completion, history, highlighting) → switching to zsh or fish is worth it
  • Scripts, server administration, portability → stay on bash; no need to switch
  • Don't want to spend time configuring → fish (great out of the box)
  • Want bash compatibility while gaining features → zsh (most existing scripts just work)

Key premise

You only switch the login shell you use interactively. Scripts that start with #!/bin/bash still run under bash no matter what you switch to. Treat the two as separate concerns.

The feature-by-feature comparison itself is covered in bash vs zsh vs fish. This article focuses on deciding whether to actually switch and on doing the migration and handling its problems.

What actually changes when you switch?

Conclusion: What changes is interactive comfort (completion, suggestions, color) and your config file. The script execution environment does not change.

Here is what you actually feel after switching.

Where you notice it bash zsh fish
Tab completion basic strong (menu) smartest
History-based suggest none plugin needed built-in (dim)
Inline syntax color none plugin needed built-in
Config file ~/.bashrc ~/.zshrc ~/.config/fish/config.fish
Existing bash scripts run mostly run do not run

fish's interactive comfort is its main appeal, but POSIX syntax like VAR=value, export VAR=..., and if [ ... ] does not run as-is. Copying your .bashrc into fish will not work. This incompatibility is the number-one source of migration pain.

How to decide which shell to switch to

Conclusion: Choose zsh to carry over your existing bash config, fish to get comfort from scratch. When unsure, zsh is the safe default.

Asking yourself these in order usually settles it.

  1. Do you have many aliases / functions / PATH tweaks in .bashrc?
    • Yes → zsh (nearly identical syntax, easy to port)
    • No → next
  2. Do you want comfort the moment you install, rather than writing config?
    • Yes → fish
    • No → next
  3. Do you want the Oh My Zsh theme/plugin culture?
    • Yes → zsh
    • Either is fine → zsh (more material, fewer dead ends)

The golden rule: before you chsh, just launch the shell temporarily to try it. Typing zsh or fish drops you in without changing your login shell. exit returns you to bash.

Migrating to zsh

Conclusion: Install → try → make default with chsh → move the parts of .bashrc you need into .zshrc. Four steps.

1. Install and try it

# Ubuntu / Debian
sudo apt install zsh

# Launch first, without changing your login shell
zsh

On first launch the zsh-newuser-install wizard appears. You can press q to skip and configure later.

2. Make it the default shell

chsh -s "$(which zsh)"

A chsh change takes effect on your next login (reopen the terminal), not the current session. After it applies, confirm with echo $SHELL that it reads /usr/bin/zsh or similar.

3. Carry over your bash config

Because zsh's syntax is close to bash, most aliases, functions, and PATH additions in ~/.bashrc paste straight into ~/.zshrc and work. Bash-specific completion (bash-completion) and PROMPT_COMMAND, however, need zsh equivalents.

# Pastes into .zshrc and just works
alias ll='ls -alF'
export PATH="$HOME/.local/bin:$PATH"

To set up completion and themes in one shot you can add Oh My Zsh, but it can slow startup, as noted in the shell comparison.

Migrating to fish

Conclusion: fish is not POSIX-compatible, so your .bashrc cannot be ported. Plan to rewrite config in fish syntax.

1. Install and try it

# Ubuntu / Debian
sudo apt install fish

# Launch without changing your login shell
fish

2. Make it the default shell

# Confirm fish's path is registered in /etc/shells
grep fish /etc/shells

chsh -s "$(which fish)"

3. Write config in fish syntax

bash's export and VAR=value do not work in fish. Here are the key rewrites.

# bash:  export PATH="$HOME/.local/bin:$PATH"
# fish:
set -gx PATH $HOME/.local/bin $PATH

# bash:  alias ll='ls -alF'
# fish (alias works, but functions are preferred):
alias ll='ls -alF'

fish builds interactive completions from man pages, so even with zero config you get option completion for many commands. That is why it is called "comfortable without configuration."

Common migration traps

Conclusion: Most snags are running a script under fish syntax, assuming chsh is instant, or editing the wrong config file.

You edited ~/.bashrc but nothing changed

After switching, the file that loads is ~/.zshrc for zsh or ~/.config/fish/config.fish for fish. Your bash config files are no longer read by the interactive shell. Make sure you are editing the right one.

Shell scripts fail under fish

> export FOO=bar
fish: Unsupported use of '='. ...

fish is not POSIX-compatible. To run a .sh script, do not stay in fish; run it explicitly with bash.

bash ./deploy.sh

If the script starts with #!/bin/bash and is executable, ./deploy.sh runs it under bash even when your login shell is fish.

chsh did not take effect

chsh applies from the next login. Reconnect over SSH, or reopen a desktop terminal. If you only want a quick try, skip chsh and launch by name (zsh / fish).

How to roll back

Conclusion: The bash binary never disappears, so chsh -s /bin/bash brings you back anytime. Switching is reversible.

If zsh / fish does not suit you, just set the default back to bash.

chsh -s /bin/bash

Even if a broken login shell locks you out of the terminal, you can recover from another user or a rescue console by editing the trailing shell path of your line in /etc/passwd back to /bin/bash. chsh only rewrites /etc/passwd.

If you keep the zsh / fish packages installed, you can mix them: fish for interactive use, bash for verifying scripts. Switching is not a decision to throw any one of them away.

Next Reading