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.
Startup and Related Files
As a user one should understand the different files there are. They are in ZDOTDIR
is usually ~
but can be overridden:
- Commands are first read from
/etc/zshenv
and then$ZDOTDIR/.zshenv
- If the shell is a login shell, commands are read from
/etc/zprofile
and then$ZDOTDIR/.zprofile
. - If the shell is interactive, commands are read from
/etc/zshrc
and then$ZDOTDIR/.zshrc
- if the shell is a login shell,
/etc/zlogin
and$ZDOTDIR/.zlogin
are read. - 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
:
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
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:
- Run
zle -la
orman zshzle
- Install
zsh-doc
- 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
The function _git-diff
will do this
- Pushes the command on the edit buffer stack, and pull it back the next time ZLE is available.
- Run a
git diff
by setting the command and running the widgetaccept-line
- After execution of
git diff
the widgetpush-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.