Z shell vs Bash

- 9 mins

This article is meant to show the main differences and advantages of the Z shell(Zsh) over the Bourne-again shell(aka Bash).

For the inpatients, the main advantages of using Zsh are:

These apply only to the interactive shell, when writing scripts or programs in shell scripting, except if you won’t care about portability, it’s better to conform to the POSIX standard.

Zsh comes with a builtin compiler (zcompile) with which is possible to compile scripts or functions. The advantage of having a compiled version of a script or function is mainly speed. It support floating point calculations (Bash not) and has a reach math function library.

Finally Zsh support all the functionalities of Bash, so you can reuse any Bash script without changing anything.

An in-depth view

Some years ago, moved by an impelling need for change, I started using the Z shell. Coming from Bash and the KornShell(ksh), I was at first quite lost, lost as you would be if you start using a vanilla bash without any prompt customization, aliases, colors, custom functions and so forth. In my quest to find quickly the bit of information to setup Zsh for my needs, I discovered Oh My Zsh, an open source framework for managing your Zsh configuration. It comes bundled with thousands of helpful functions, helpers, plugins and themes. Easy Peasy, I got my Zsh setup in a lightning bolt and forgot about my good intentions of learning the deepest secrets and niceties of Zsh. I’ll come back to Oh My Zsh later, but keep in mind that using a framework, while it’s extremely useful, it’ll hide all the subtle and interesting details.

General characteristics

  Zsh Bash
Usual environment POSIX POSIX
Usually invoked zsh bash, sh
Introduced 1990 1989
Platform-independent Yes Yes
Default login shell in Deepin, GoboLinux, Grml, macOS 10.15+ GNU, Linux (default for root), macOS 10.3–10.14
Default script shell in Grml, macOS 10.15+ GNU, Linux, Haiku, macOS 10.3–10.14
License MIT-style GPL
Mouse support via additional code No
Configurability Yes (via variables, options, functions, styles, etc.) Yes (via variables and options)
Startup/shutdown scripts Yes (system and user’s zshenv, zprofile, zshrc, zlogin, zlogout) Yes (/etc/profile, .bash_profile, .bash_login, .profile, .bashrc)

As highlighted in the above table, with an additional plugin, Zsh has mouse support for basic actions, like text selection, copy and pasting. Functionality that usually is provided by the terminal itself.

Interactive features

  Zsh Bash
Command name completion Yes Yes
Path completion Yes Yes
Command argument completion when defined when defined
Wildcard completion Yes Yes
Command history Yes Yes
Automatic suggestions Yes (via predict-on or user-defined) No
Colored directory listings Yes Yes
Text highlighting Yes Yes
Syntax highlighting Third-party extension No
Directory history, stack or similar features Yes Yes
Implicit directory change optional optional
Auto­correction Yes No
Snippets when defined (as ZLE widgets) No
Value prompt Yes Yes
Menu/options prompt Yes Yes
Context sensitive help Yes No

In the following terminal recording (made with termtosvg) you can see some of the main advantages of the Zsh completions and auto-corrections functionalities.

While with additional plugins and scripts you can obtain almost the same functionalities with bash, Zsh provides these out-of-the-box.

Some examples

$ echo **/*\.sass
_sass/base/general.sass _sass/base/helpers.sass _sass/base/syntax.sass _sass/base/variables.sass _sass/components/author.sass _sass/components/disqus.sass _sass/components/footer.sass _sass/components/header.sass _sass/components/nav.sass _sass/components/others.sass _sass/components/pagination.sass _sass/components/related.sass _sass/components/share.sass _sass/components/side-by-side.sass _sass/components/social-links.sass _sass/components/spoiler.sass _sass/pages/home-blog-projects.sass _sass/pages/page.sass _sass/pages/post.sass _sass/pages/tags.sass
$ alias -s markdown=vim
$ ./_posts/2018-06-14-vim-safe.markdown

When “executing” a .markdown file, it will be opened directly with vim.

$ ls -tld *(m+100)
-rw-rw-r-- 1 antenore antenore   117 Jun 16  2018 _config-dev.yml
-rw-rw-r-- 1 antenore antenore   212 Jun 16  2018 Rakefile
drwxrwxr-x 5 antenore antenore  4096 Jun 16  2018 _sass
drwxrwxr-x 2 antenore antenore  4096 Jun 12  2018 blog
-rwxrwxr-x 1 antenore antenore    33 Jun 12  2018 index.html
-rw-rw-r-- 1 antenore antenore   603 Jun 12  2018 projects.html
-rw-rw-r-- 1 antenore antenore    24 Jun 12  2018 robots.txt
-rw-rw-r-- 1 antenore antenore  1451 Jun 12  2018 tags.html
-rw-rw-r-- 1 antenore antenore   144 Jun 12  2018 travis.sh
drwxrwxr-x 3 antenore antenore  4096 Jun 12  2018 assets
-rw-rw-r-- 1 antenore antenore 34466 Jun 12  2018 LICENSE
-rwxrwxr-x 1 antenore antenore     1 Jun 12  2018 README.md
-rw-rw-r-- 1 antenore antenore   722 Jun 12  2018 FAQ.md


  Zsh Bash
Functions Yes Yes
Exception handling Yes Yes (via trap)
Search & replace on variable substitutions Yes (via ${:s//} and ${//} syntax) Yes (via ${//} syntax)
Arithmetic Yes Yes
Floating point Yes No
Math function library Yes (zsh/mathfunc module) No
Linear arrays or lists Yes Yes
Associative arrays Yes Yes
eval function Yes Yes
Pseudo­random number generation Yes ($RANDOM) Yes ($RANDOM)
Bytecode Yes (built-in zcompile command) No

As said, from a programming point of view, Bash and Zsh are quite the same, the most interesting difference are the math functions and the floating point support in Zsh.

# Zsh
$ echo $((0.5 / 0.2))
# Zsh
bash-5.0$ echo $((0.5 / 0.2))
bash: 0.5 / 0.2: syntax error: invalid arithmetic operator (error token is ".5 / 0.2")
bash-5.0$ echo $((5 / 2))
$ zcalc -e "sqrt(2)"
$ print $(( [#_] sqrt(1e7) ))

Setting up Zsh

On Bash you are quite on your own to configure your environment, on the contrary, if not deactivated by the OS distributor, or by your system administrator, in Zsh there’s a function that is called if you don’t have the rc files in your home (i.e. .zshrc).

The function, zsh-newuser-install, will interactively help you to setup most of the default behaviour. It can be called by hand if it has been disabled or if you wish to start from scratch:

$ autoload -Uz zsh-newuser-install
$ zsh-newuser-install -f
Please pick one of the following options:

(1)  Configure settings for history, i.e. command lines remembered
     and saved by the shell.  (Recommended.)

(2)  Configure the new completion system.  (Recommended.)

(3)  Configure how keys behave when editing command lines.  (Recommended.)

(4)  Pick some of the more common shell options.  These are simple "on"
     or "off" switches controlling the shell's features.

(0)  Exit, leaving the existing ~/.zshrc alone.

(a)  Abort all settings and start from scratch.  Note this will overwrite
     any settings from zsh-newuser-install already in the startup file.
     It will not alter any of your other settings, however.

(q)  Quit and do nothing else.
--- Type one of the keys in parentheses ---

This method is easier than setting everything by hand, but still a hurdle for those that do not know yet the basic Zsh builtin and functions.

To alleviate the problem there are some different framework that hide all the difficulties and easy the setup. The one I use and know is Oh My Zsh, it features a quite huge quantity of plugins, themes and functions, and, most importantly, it’s very easy to setup.

Just follow the installation instructions on their site, but do not forgot, afterwards, to read man zshall ;-)



Some of the content has been taken form Wikipedia.

Antenore Gatta

Antenore Gatta

A proud and busy Hacker, Father and Kyndrol