Rate this page del.icio.us  Digg slashdot StumbleUpon

Zero to Z-Shell: Learn what all the fuss is about with Z-Shell


By and large, most Red Hat Linux systems will have Bash as the default shell. Bash is a darn great shell, but this article is about another equally great shell, called Z-Shell, that has most of the attributes of Bash, but in some cases goes the extra mile to give you the flexibility to customize your shell more than Bash allows.

This article is somewhat advanced, but if you’re very patient, with some effort, you will do just fine. Remember to make small changes, test them, and then make more small changes, test, and repeat.

First a few basics. I would encourage you to fire up a shell and test out this code while you read.

Basic configuration and setup

Switching your default shell to zsh

Before you start hacking away and changing config files, you need to do a few things first. Since Bash is the default shell, you will need to change things to Z-Shell, at least temporarily, while you follow this article. By far the easiest way to change your shell is to use the chsh command.

To quickly change to zsh, issue this command:

chsh -s /bin/zsh

If you take a peek at your /etc/passwd file:

less /etc/passwd 

You will see that the default shell for your user account has been changed. This is a permanent change, and when you log back in again you will stay with the zsh.

Z-Shell Configuration Files

The good and bad of it is that zsh can have as many as eight different configuration files. This is the order of execution that you should know about for the most common files:

1. /etc/zshenv – Always executed global configuration file.
2. ~/.zshenv – Local configuration file.
3. /etc/zprofile – Global Login shell configuration.
4. /etc/zshrc – Global interactive shell configuration.
5. ~/.zshrc – User interactive shell configuration.

The most efficient file to edit is probably ~/.zshenv as it will configure both interactive and non-interactive shells. For all of the examples I show below, please edit the ~/.zshenv file.

Backing up your configuration files or using version control

One thing I always caution is to backup your original file or use version control. One of the absolute worst situations to be in is with a damaged configuration file and no way to return to the original state. Make a backup of any file you edit, or better yet, use version control!

Z-Shell Cookbook

Since there are so many things you can do with Z-Shell and no way to talk about them all, I’m going to give you as much as possible through a cookbook format. I will go through the “recipes,” and you can “cook” along with your shell at home. Did you you remember to make a backup of your original files? Great, lets get started!


Z-Shell has incredible autocompletion tools. Here are few barebones examples:

In order to use autocompletion, you will need to put the following in your ~/.zshenv file:

#Allows prompt profiles
autoload -U promptinit

With zsh you can autocomplete things other than just file. If you type in:


you get variable completion.

If you use something like gunzip in a directory with .gz files it will just figure out what files it should work with if you keep selecting tab. Try it out.

If you’re in the mood to get really geeky, check out completion functions in zsh. I don’t cover them in this article, but they are worth investigating.

Command history and history substitution

Mastering the use of command history will save you many keystrokes!

Remove mistakes:

root@cent]~# lesss /var/log/messages
zsh: command not found: lesss
[root@cent]~# ^s
less /var/log/messages

Remember commands:

[root@cent]~# ls /var/log/messages
[root@cent]~# !!
ls /var/log/messages
!$ Last Argument on the previous command line
cp !$ .
(copies /var/log/messages to current directory)

Rerun previous commands:

root@cent]~# !l
ls /var/log/messages

This works because ls is in the history.

Finally, you can substitute by a command line number.

[root@cent]~# !32
ls /var/log/messages

Key bindings

Key bindings literally bind things to certain keys. Instead of using readline like Bash, zsh uses Zsh Line Editor or zle. In Bash you use bind and in zsh you use bindkey.

In zsh to find out what keys are bound:

bindkey -L

To see the whole list of editor commands that can be bound, and it is huge:

zle -la

I would recommend exploring keybindings by piping the list of your currently bound keys to less:

bindkey -L | less

Job Control

An example of using job control in Z-Shell:

tail -f /var/log/messages &
kill %1

If you have a long-running process, you might want to let it work in the background while you continue other things. For example, if you download a tool I wrote called Liten, you may want to run it as a background job, as it will search a directory tree and do md5 checksums on files to find duplicates. This may take quite a while to completely get through a large file system, so it’s a perfect choice to run in the background.
Go ahead and run liten on your home directory as a background process:

./liten.py $HOME

Then click Ctrl+Z to send the job to the background.
The output will be:

zsh: suspended  ./liten.py $HOME

Then run:


And the output will be:

[1]  + suspended  ./liten.py $HOME
root@cent]~# bg %1
[1]  + continued  ./liten.py $HOME

If you have only one suspended job, you can use the shortcut:


You can also set an option in zsh to resume jobs by name:

setopt auto_resume

This lets you resume a job just by typing in the name of the job. It’s quite handy!

Remember that if you put a job in the background, you might want to pipe stdout somewhere while it runs.

When you exit the shell and you have a running job, zsh will kill the jobs by giving them a SIGHUP signal. Here are ways to tell zsh to prevent killing the jobs on exit:

  • Use nohup in front of jobs you want to run on exit. Make sure it used in this manner:

    nohup top &
  • You can also let your job run wild and give it the disown command or followup the the job with

Priority of background jobs

In zsh, background jobs are automatically given a lower priority unless you set an option.

Process substitution

One neat feature zsh has is the special =(…) substitution.For example, if you want to find out the full path to a program you can do run:

ls =top

The output will be:


I personally think this shorthand is quite nice, and I commonly find myself needing to find the full path to some command.

Another example would be when you want to use a shell command to format stdout and then
edit it in a text editor like vi:

vim =(tail < /var/log/messages)

Customizing Prompt

Like just about everything else in Z-Shell, the prompt is extremely customizable. If you would like to check out a few of the themes, you can set your .zshenv to allow prompt switching:

#Allows prompt profiles
autoload -U promptinit

You can now view available prompt themes by typing:

prompt -l

You can also select and then set with the following:

prompt oliver
prompt -s

You will get back something like this:

prompt -s oliver
Set and save not yet implemented.

Please ensure your ~/.zshrc contains something similar to the following:

  autoload -U promptinit
  prompt oliver

If you want to get really fancy, you can also edit the following in your .zshenv file:

#Customize Prompt
PROMPT=$'[%n@%m][H:%B%!%b][J:%B%j%b]> '

This is actually my current prompt, but feel free to tweak it around a bit; that’s how you learn. I won’t go any more into the details of customizing prompts here, but you should read through the Z-Shell manual.

File and directories

If you set:

setopt autocd

It will allow you to cd into a directory without typing cd first.

If you set:


It will allow you to cd to a variable, such as:


Shortcuts for referring to directories

Get back to the directory you were just in:
~- same as $OLDPWD

Some fancy stuff:
~2 Second directory on the directory stack.
~-0 Final directory on the directory stack.

This works in conjunction with the pushd and the popd commands, which I won’t get into in this article, but you can read more here.

Using braces

Create ten test files in a few keystrokes:

touch {1..10}.txt


Z-Shell is a mind-blowing shell with the ability to tweak and change just about anything. What I covered in this brief survey article barely does Z-Shell justice. If you are interested in knowing more about Z-Shell or Bash, I would highly recommend reading, From Bash To Z-Shell by Oliver Kiddle, Jerry Peek, and Peter Stephenson. It is truly a masterful book! Of course, you can’t go wrong by reading the official documentation either.

Finally, I would love to hear back on some extra tricky things you have done with your Z-Shell.

7 responses to “Zero to Z-Shell: Learn what all the fuss is about with Z-Shell”

  1. mauilion says:

    Actually I have tried to work with both ZSH and Bash. I have to admit that I am more comfortable with bash. The one thing no one seems to compare is the bash-completion package available via most distros. This creates quite a large autocompletion feature that is oft overlooked. With bash-completion I can autocomplete hosts listed in my ~/.ssh/known_hosts file. I.E. ssh root@haiku.flabbergasted.com

    I was unable to get this feature working in zsh.


    Duffie Cooley

  2. Sam says:

    “Learn what all the fuss is about with Z-Shell”

    .. what fuss??

  3. chandrakant says:

    i have configure a linux server so pl. send me detail i have a condigure both server like mail server and web server and data server ftp & telnet & ssh & scp & samba server file server and data server so pl. help me how to configure both server in linux and client is windows i have waiting for mail and solution pl. mail me.

  4. Benjamin Andresen says:

    Well, the good thing with zsh is that is can use bash completion… It has an emulation mode.

    So in the end it is impossible for bash to get more completion than zsh, because zsh already has a big base.

    Not comparing quality here, just saying. ;-)

  5. Matěj Cepl says:

    I tried zsh and although its capabilities are impressive, even in the recent version (on FC6) I had terrible problems with UTF-8 support (or rather non-support) in zsh. I got couple of file names with diacritic in their names badly mangled by zsh. Nice as it seems to be, this is showstopper for me (being Czech, diacritic happens even in the file names — think automatically generated names of .ogg files).

  6. Matthew Flaschen says:

    Great article. I was unaware of ^s
    and the second = trick (e.g. tail

  7. Matthew Flaschen says:

    My comment got cut off. Here it is again

    Great article. I was unaware of ^s
    and the second = trick (e.g. tail < /var/log/messages). mauilion, keeping your ~/.ssh/known_hosts in plain text is a security risk. See http://itso.iu.edu/Hashing_the_OpenSSH_known__hosts_File .