Table of contents
Commonly, when we’re speaking about Linux servers or Docker containers, we usually mean a command-line interface, shell, or terminal experience. There are two widely used shells by the community: Bash and Zsh. The Bash is considered the most widely used shell. At the same time, Z shell or Zsh becomes more and more popular nowadays. So, which terminal you should choose? In this article, we’ll compare Bash vs Zsh and try to answer the question of which terminal is better.
History
Bash shell (Bourne Again Shell) was introduced in 1989 to replace Bourne Shell and it became the default Linux shell very quickly. Bash is capable of performing a wide range of programming solutions and automated tasks in Linux, but that’s not the only shell that you can use. There are several other shells that can perform similar functions as Bash.
One of them is Zsh, which was created in 1990 as an extended Bourne shell with many additional features of Bash, ksh, and tcsh. If you are a Linux user, you do not have to install Zsh separately since it is included by default in almost all modern distributions. Bash and Zsh share some features, but there are also many differences between these shells, which we’ll describe in this article. This article covers the following sections:
- Features comparison table
- Terminal UX Comparison
- List of differences between Bash and Zsh
Now let’s head towards the first section of this article.
Features comparison
I this part we’ll cover the the most important differences.
Zsh | Bash |
It contains a lot of advanced features. | It does not contain advanced features. |
Has a more complex configuration file structure. | Configuration files structure is simple. |
Configuration and customization is provided by Oh My Zsh framework. | Configuration and customization is provided by Bash-it. |
Commands history is shared across all shells. | History sharing is difficult. |
Zsh scripts are not so widely used. | Bash scripts are widely used. |
Zsh does not load SHELLOPTS during startup. | SHELLOPTS are loaded during the start. |
Environment configuration is more customizable with zshrc , zlogin , zshenv , zlogout , zprofile . | Environment is less customizable and can be implemented with a fewer scripts. |
Allows using expanded aliases anywhere in the file. | Bash does not support the expanded aliases by default. |
zparseopts makes scripts arguments parsing very easy. | Parsing script arguments with getopts is a bit more challenging. |
Terminal calculations can be done using zcalc . | You need to use two external calculators: bc and expr . |
Terminal configuration/autostart scripts are loaded from ~/.zshrc file. | Terminal configuration/autostart scripts are loaded from ~/.bashrc file. |
bindkey is used for keys binding. | bind builtin and ~/.inputrc are used for key binding. |
More options to build fancy prompts. | Less options for fancy prompts. |
setopt responsible for shell settings. | shopt configures shell settings. |
# is not considered a comment unless INTERACTIVE_COMMENTS is set. | # represents a comment string. |
Extended wildcard patterns enabled by default. | Use shopt -s extglob to enable extended wildcard patterns. |
More ways to transform the variable value (parameter expansion). | Fewer methods for transforming variables. |
Has auto completion and spellings correction features embedded. | You need to use bash-completion package. |
More plugins and themes available. | Fewer plugins and themes available. |
Zsh is more customizable. | Bash is less customizable. |
POSIX compatible if emulate sh has been set. | Follow POSIX standards if --posix command-line option was set. |
Auto completion works faster. | Auto completion is slower. |
Smaller community | Wider community |
Bash vs Zsh – Internet search volume
Here’s a Google Tends chart, which shows the search volume comparison for both shells:
Bash vs Zsh – UX
In this section we’ll review most commonly used UX shell features, which you use on a daily basis.
Docker container setup
If you just want to test the following examples, the best way of doing this is to launch Ubuntu Docker container:
docker run -it ubuntu:20.04 /bin/bash
Docker container does not have Zsh installed by default, so, you have to install it first:
apt-get update
apt-get install -y zsh
Finally, you may launch zsh shell:
zsh

Tab for auto completion
The Tab
key usage in Zsh and Bash a bit different. Let’s create a a couple of nested directories to illustrate this example:
mkdir -p onedrive/docs
mkdir -p onedrive/pics
In Bash, you have to use Tab
key to auto complete the path to the directory or file.
For example, type one, then press Tab
, the type d and press Tab
again to finalize the path in terminal:
cd onedrive/docs
Expected result should look like this:

In Zsh, usage of the Tab
key will provide you the list of available options to select from.
Type one and press Tab
, then press Tab
again as many times as you’d like to select required directory:

Spelling correction
The spelling correction functionality is supported by both Zsh and Bash shells. However, Zsh does it more effectively.
In the example below, you will learn how to enable Zsh and Bash to correct the spelling automatically.
Let’s create a directory named onedrive
, if you did not do that at the previous part of the article:
mkdir -p onedrive
Now let’s make a typo in Bash shell command:
cd onedrave
Bash shell will not correct the typing mistake of “drave” to “drive,” and display the error “No such file or directory.”

To enable the automatic spell checking feature in bash, you have to edit the Bash configuration.
nano ~/.bashrc
Add the following line at the end of the file:
shopt -s cdspell

Use the source
command to apply changes to the shell.
source ~/.bashrc
Execute the misspelled command again. The Bash terminal automatically corrected the typo:
cd onedrave

What about Zsh?
Lets misspell “echo” command to check if Zsh detects and corrects it for us automatically:
ehco "Hello World"
As expected, Zsh did not fix the spelling.

Now, we will make some changes to the Zsh configuration.
nano ~/.zshrc
Turn on the correctexport
option for the shell. You may also specify prompt message too:
setopt correct
export SPROMPT="Correct %R to %r? [Yes, No, Abort, Edit ]"
Do not worry if the file is empty, it is OK, it will be populated with additional configuration as soon we will install Oh My Zsh later.
Here’s how it should look like if you’re following us in the Docker container:

Execute the source
command to apply changes to the shell.
source ~/.zshrc
Execute the misspelled echo
command again:
ehco "Hello World"
Here you go!
Automatic spell-checking is now enabled:

Themes
You need to install Git to be able to use any Bash or Zsh themes and customizations:
apt-get install -y git
To install customizations for the Bash shell, use the following command:
git clone --depth=1 https://github.com/Bash-it/bash-it.git ~/.bash_it

Installation process is very simple:
~/.bash_it/install.sh

Now we can edit ~/.bashrc
file to edit Bash theme:
nano ~/.bashrc
Change BASH_IT_THEME
variable value to any theme that exist in the theme bundle, for example, try envy.

To apply changes, execute the following command:
source ~/.bashrc

Now, let’s customize Zsh.
As mentioned previously, Oh My Zsh framework provides a lot of useful features and extensive themes collection.
Oh My Zsh installation is not very difficult too:
apt install -y curl wget git
sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Just answer Y to all the questions and you’ll get beautiful shell customization by default:

Now, Zsh themes are located in: ~/.oh-my-zsh/themes
folder:
ls ~/.oh-my-zsh/themes/
Here, you can see the names of the themes included in the bundle.

The default theme of Zsh is “robbyrussell“. To modify this theme, update the ZSH_THEME
variable value in ~/zshrc
file:
nano ~/.zshrc
Now edit the ZSH_THEME
variable value to set up a new theme for your terminal. Here’s a list of UX examples.

To apply changes, use the source
command:
source ~/.zshrc

Wildcard expansion
File names are used to match with the wildcards. Bash has this built-in feature in it, whereas for Zsh, you have to enable the wildcard expansion by setting the global subset.
Let’s create a couple of .txt
files in Bash:
touch text_file1.txt
touch text_file2.txt
ls

Now, we can list our .txt
files by using the wildcard expression in a variable:
files="*.txt"
echo $files

In Zsh such approach will not work by default:
touch text_file1.txt
touch text_file2.txt
ls
file="*.txt"
echo $file

set -o GLOB_SUBST
file="*.txt"
echo $file

Now, wildcard expressions are working!
Put this option to ~/.zshrc
, if you’d like to keep such behavior of Zsh in the future:
set -o GLOB_SUBST
Summary
Both Zsh and Bash, are extremely powerful shells with lots of extensions and configuration options. Zsh has robust customization, extensibility, and advanced features. Bash is still more widely used, so think about it backward compatibility of your scripts with other systems you might need to manage.
My personal choice is Zsh when it comes to personal laptop, and Bash when it comes to a server management activities.
I hope, this article was useful for you. If so, please, help us to spread it to the world!
Related articles
- How To Install Oh My Zsh on Ubuntu
- Bash If-Else Statements – All You Need to Know About
- How To Rename Files And Directories In Linux
- Terraform – Managing Auto Scaling Groups & Load Balancers
- Bash For Loop – The Most Practical Guide
How useful was this post?
Click on a star to rate it!
We are sorry that this post was not useful for you!
Let us improve this post!
Tell us how we can improve this post?
I’m a passionate Cloud Infrastructure Architect with more than 15 years of experience in IT.
Any of my posts represent my personal experience and opinion about the topic.