A brief difference between zsh and bash
Tags: bash, zsh, productivity, shell
Published: 2020-03-01 14:55:37


Shell is an interface between the user and operating system services. It provides multiple features like background processing, input and output redirection, aliasing, link, and chain commands, etc. which makes the life of developers easy. I have started using zsh for quite some time and found it more effective than bash. So here I have curated the list of differences between the two which has helped me a lot to understand.

So let's compare these two shells on certain basis and find out the differences.

##Performance##
It is one of the useful means of benchmarking the shell's performance. To evaluate this let's generate some load and check how fast the shell responds.

* I have compared the speed of both the shell once invoked by running the 
   following command:
```time shell_name -c 'for i in $(seq 1 1000000);do [ 1 = 1 ];done'```

In the above command replace **shell_name** with zsh and bash.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/u1i9tz83cqdn9eiy9te6.png)

* I have written a script that reads input from the user and prints in for loop multiple times. This will help to check the time taken to process the script.

```bash
#!/bin/bash
# Script name: test.sh
for i in `seq 1 100`
do
    for var in $* 
    do
        echo "command line contains: $var"
    done
done
```
Run the following command in both the shell to see the script execution time in each shell.
```time shell_name ./test.sh "some_long_sentance"```
Replace the shell_name with **zsh/bash** and some long sentences in the above command.


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yzpeofe9jvrwcvt97iha.jpg)
The left and right outputs are for zsh and bash respectively.
The results in both the above snippets shows that zsh is faster than bash. The terms in the results means the following:
* **real** is the time from start to finish of the call.
* **user** is the amount of CPU time spent in user-mode within the process.
* **sys** is the amount of CPU time spent in the kernel within the process.

##Configuration Files##
Bash reads **.bashrc** file in non login interactive shell and **.bash_profile** in login shells.

Zsh reads **.zshrc** in an interactive shell and **.zprofile** in a login shell.

*Interactive shell is a simple shell that drives input from the user and returns the desired output.
A login shell is the first process that executes under our user ID when we log in to a session.*

##Key Bindings##
Any keyboard actions which are done while typing the commands on the command line like pressing Ctrl+E to move to the end of the line is called key bindings. It uses a completely different syntax.

Bash uses [.inputrc and bind builtIn](https://www.gnu.org/software/bash/manual/html_node/Readline-Init-File.html) to bind keys to [readline](https://www.gnu.org/software/bash/manual/html_node/Bindable-Readline-Commands.html) commands.

Zsh uses [bindkey builtIn](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#index-bindkey) to bind keys to [zle widgets](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Standard-Widgets).

##Prompt##
Bash sets the prompt from **PS1** which contains backslash escapes like **\a** whereas zsh contains the percent escapes like **%d**. The functionality of bash PROMT_COMMAND  is available in zsh via **precmd**.
Zsh also offers ways to do fancy customizations.


##Completion##

Both the shells provide features like command completion and switching to fancy mode. In bash it is done by including **bash_completion** while zsh achieves this by running **compinit**.
More about zsh [Completion System](http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System).

##Scripting differences##
* The processing of variables is the same in both zsh and bash. Let's 
  assume we have a variable `$var`, both the shells will take the value of 
  var splits it at whitespace characters, and for each whitespace- 
  separated part, if it contains wildcard characters and matches an 
  existing file replaces the pattern by the list of matches. To just get 
  the value of `var` we need `$var`

* Length of an array in bash is from 0 to length-1 whereas it ranges from 
  1 to length in zsh.

* Bash has extra wildcard pattern which can be enabled by `shopt -s 
  extglob`. In zsh same can be achieved by using `setopt ksh_glob` 
  or `setopt extended_glob`for simpler to type native syntax.

There are some nice zsh features like [Glob Qualifiers](http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers) and [widcard patterns](http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Operators) that bash doesn't offer. There are many zsh configuration frameworks on the web. They can be a convenient way to get started with some powerful features.