What is ZSH and why I prefer it over bash

Posted on September 12, 2022 by Adrian Wyssmann ‐ 5 min read

When you work on Linux, you usually have bash as your default shell. I already switched a long time ago to Z-Shell cause it has some neat features, which improves my productive massively.

What is Z-Shell

ZSH stands for Z shell and is one of the mans shells available on Linux.

is a shell designed for interactive use, although it is also a powerful scripting language. Many of the useful features of bash, ksh, and tcsh were incorporated into zsh; many original features were added.

The websites summarised the features as follows:

Command line editing:

  • programmable completion: incorporates the ability to use the full power of zsh’s globbing and shell programming features,
    • multi-line commands editable as a single buffer (even files!)
    • variable editing (vared)
    • command buffer stack
    • print text straight into the buffer for immediate editing (print -z)
    • execution of unbound commands
    • menu completion in two flavours
    • variable, editing function and option name completion
    • inline expansion of variables and history commands
  • Globbing - extremely powerful, including:
    • recursive globbing (cf. find)
    • file attribute qualifiers (size, type, etc. also cf. find)
    • full alternation and negation of patterns
  • Handling of multiple redirections (simpler than tee)
  • Large number of options for tailoring.
  • Path expansion (=foo -> /usr/bin/foo)
  • Adaptable messages for spelling, watch, time as well as prompt (including conditional expressions)
  • Named directories
  • Comprehensive integer and floating point arithmetic
  • Manipulation of arrays (including reverse subscripting)
  • Associative arrays (key-to-value hashes)
  • Spelling correction

I am by no means a zsh expert and I won’t go trough all the stuff it offers. However I would present you some of the features which makes my day more productive when using zsh.

You might have a look at the [shell grammar] to understand in details how to interact with zsh. Like bash, zsh has some builtin-commands, like cd - to change directories - oralias - which allows you for aliasing. A simple command may be preceded by a precommand modifier, which will alter how the command is interpreted. In addition, as a separate part of the core, there exist modules to extend the shell. Modules can be linked in to the shell at build time, or dynamically linked, using zmodload, while the shell is running.

The shell itself can be configured using various options. For example setopt AUTO_CD will automatically cd into a directory if you enter a directory instead a command on the shell.

As a user one should understand the different files there are. They are in ZDOTDIR is usually ~ but can be overridden:

  1. Commands are first read from /etc/zshenv and then $ZDOTDIR/.zshenv
  2. If the shell is a login shell, commands are read from /etc/zprofile and then $ZDOTDIR/.zprofile.
  3. If the shell is interactive, commands are read from /etc/zshrc and then $ZDOTDIR/.zshrc
  4. if the shell is a login shell, /etc/zlogin and $ZDOTDIR/.zlogin are read.
  5. When a login shell exits, the files $ZDOTDIR/.zlogout and then /etc/zlogout are read.

Auto completion

Zsh uses a completion system called compsys and is written in shell functions and is contextual, sensitive to the point at which completion is started. This means completion can be

  • a command
  • an argument
  • special context

To enable auto-complete this is the minimal configuration required in .zshrc:

autoload -Uz compinit
compinit

Here an example of the auto completion with ls. As you can see - if configured so - options can be autocompleted by using a menu:

Looking at the documentation the [completion systems] seems very powerful but also complex. Luckily there is an excellent article, which explains in a lot of details on how it works.

Zsh Line Editor (ZLE)

Zsh Line Editor (ZLE) is the interface to the shell interpreter and allows you to write and edit commands. To fully grasp the idea, you neded to understand two thinks

  • [keymaps] and [keybindings][keymaps]
  • widgets

A [keymap][keymaps] is a set of keystrokes, which execute a ZLE command ord ZLE Widget. For example

bindkey '^g' clear-screen

binds Ctrl+g to the ZLE command clear-screen, which will clean the shell (same as you would type cls). You can type bindkey to see what keybindings are set. Then there are widgets, in essence is an element which performs small actions.

All actions in the editor are performed by ‘widgets’. A widget’s job is simply to perform some small action. The ZLE commands that key sequences in keymaps are bound to are in fact widgets.

There are builtin-widgets, which you can find more information here:

  1. Run zle -la or man zshzle
  2. Install zsh-doc
  3. Check online

But you can also write your own widgets. User-defined widgets are defined using zle -N, and implemented as shell functions. I take the example from this article, which describes it in more details. In this example, while writing a command you want to do a git diff and the go back and work on the command

function _git-diff {
    zle push-input
    BUFFER="git diff"
    zle accept-line
}

zle -N _git-diff
bindkey '^Xd' _git-diff

The function _git-diff will do this

  1. Pushes the command on the edit buffer stack, and pull it back the next time ZLE is available.
  2. Run a git diff by setting the command and running the widget accept-line
  3. After execution of git diff the widget push-input will then restore the command from the buffer stack (incl. cursor position)

With zle -N we define the widget, which is then bound to Ctrl-d. This is just a glimpes of what is possible, but it already shows you how powerful zsh is.

Extensions

Know that we learned some of the cool features of zsh, you can take it to the next level and extend the functionality of your zsh by adding more cool stuff like OhMyZsh

delightful, open source, community-driven framework for managing your Zsh configuration. It comes bundled with thousands of helpful functions, helpers, plugins, themes, and a few things that make you shout oh my zsh.

But there is a lot more than that. For example there are configuration frameworks like zi or prezto, plugins from other places, themes like powerlevel10k and and and. I recommend to have a look at zsh-lovers as well as awesome zsh and zshwiki to find more.

Conclusion

zsh is a very powerfull shell, and in combination with the extensibility. I personally use zi, lot of plugins from OhMyZsh and powerlevel10k as my theme. In addition I also use some plugins, not part of OhMyZsh. Here an example of my shell and the auto completion while running kubectl get ns

Looks nice isn’t it? And yeah it makes my daily work so much more productive.