Zsh (Z shell) is an interactive and scriptable shell, valued for its smart autocompletion, its plugin management and its deep customisation. Largely compatible with Bash while going much further, it is the default shell of macOS and a favourite of administrators and developers who live in the terminal. This guide shows how to install it, use it, and make it productive with Oh My Zsh and Powerlevel10k. Audience: Linux users comfortable on the command line. Behaviours checked with Zsh 5.9 on Debian 13, Ubuntu 24.04 and AlmaLinux 10.
What you will learn
- Install and configure Zsh as the default shell
- Use Zsh's smart autocompletion
- Install Oh My Zsh and Powerlevel10k for a productive terminal
- Create custom functions to automate your tasks
Installing Zsh
Let's see how to install Zsh on Linux, macOS and Windows.
Installation on Linux
On most Linux distributions, Zsh is available directly in the package repositories. Here is how to install it on the most common distributions.
Ubuntu / Debian
On Ubuntu and Debian, installing Zsh takes the following two commands, the first refreshing the package index:
sudo apt updatesudo apt install zshRHEL, Rocky and AlmaLinux
On RHEL, Rocky Linux and AlmaLinux, Zsh is in the base repositories: dnf installs it without an extra repository, unlike Fish or fzf which come from EPEL.
sudo dnf install zshArch Linux
On Arch Linux, Zsh is installed with pacman, the distribution's package manager, straight from the official repositories:
sudo pacman -S zshInstallation on macOS
On macOS, Zsh is preinstalled from Catalina (10.15) onwards. If you want a more recent version than the one shipped by Apple, you can install it through Homebrew (in French):
brew install zshOnce installed, you can check the version of Zsh with the following command:
zsh --versionInstallation on Windows
On Windows, Zsh is used through the Windows Subsystem for Linux (WSL). To install it, follow these steps:
- Install WSL with a Linux distribution such as Ubuntu.
- Open the WSL terminal and use the distribution's commands to install Zsh (for example,
sudo apt install zshon Ubuntu).
Set the default shell
For Zsh to become your default shell, run the following command, which asks for your password:
chsh -s $(which zsh)It changes your login shell in the /etc/passwd file: at the next login, Zsh starts automatically. The package itself declares Zsh in /etc/shells, the list of shells an ordinary user is allowed to choose (checked on the three distributions).
First steps with Zsh
Once Zsh is installed, the first thing to do is to configure the basic settings to adapt the shell to your needs.
Starting Zsh for the first time
To start Zsh, type zsh in your terminal. What happens on the first start depends on the distribution, and the measurement shows it. On Debian and Ubuntu, without any startup file in your home directory, Zsh opens zsh-newuser-install, a configuration menu:
This is the Z Shell configuration function for new users,zsh-newuser-install.You are seeing this message because you have no zsh startup files(the files .zshenv, .zprofile, .zshrc, .zlogin in the directory~). This function can help you with a few settings that shouldmake your use of the shell easier.
You can:
(q) Quit and do nothing. The function will be run again next time.The menu also offers to create a minimal ~/.zshrc or to set history and completion step by step. q quits without writing anything, and the menu comes back at the next start as long as no file exists. On AlmaLinux 10, no menu shows: Zsh starts directly on its default prompt.
In both cases, it is the ~/.zshrc file that then controls the behaviour of Zsh. A simple touch ~/.zshrc is enough to silence the menu; the following sections show what to put in it.
Configure your environment
One of the first elements to configure is your prompt. The prompt is the line displayed in your terminal before you type a command. With Zsh, you can customise your prompt to show useful information such as the user name, the machine name and the current directory. For example:
export PS1='%n@%m:%~%# 'This example shows the user name (%n), the machine name (%m), and the current directory (%~), followed by a # for the root user, or a % for a normal user. It is a difference with Bash, whose \$ shows $: measured, print -P '%#' returns % under an ordinary account.
The list of parameters:
- %n: User name
- %m: Machine name (hostname)
- %*: Current time in 24-hour format (
HH:MM:SS) - %~: Current directory
- %#: Shows
#if root,%otherwise - %?: Exit code of the last command run (0 on success, something else on failure)
Here are a few more complete prompt examples you can use in your .zshrc file. These prompts include extra information such as the time, the status of the last command, the user, the machine name and even Git information when you work in a repository.
export PS1='%n@%m [%*] %~ %# 'Example output:
user@hostname [14:30:12] ~/projects %export PS1='%(!.%F{red}.%F{green})%n@%m%f:%~ %# [%?] '- %(!...): Shows in red if root, in green otherwise
- %n: User name
- %m: Machine name
- %~: Current directory
- %#: Shows
#if root,%otherwise
Using colours
Colours in the Zsh prompt are configured using specific escape sequences that tell the terminal to change the colour of the text. These sequences are the %F{color} and %f codes in your prompt.
%F{color}: Changes the text colour to the specified colour.- %f: Resets the text colour to its default value (usually white or grey depending on your terminal).
The basic colours you can use are the following:
blackredgreenyellowbluemagentacyanwhite
Turn on autocompletion
Autocompletion is one of the most useful features of Zsh. To turn it on, add the two lines below to your .zshrc file:
autoload -U compinitcompinitThese commands load and initialise Zsh's autocompletion system, letting you complete command names, file paths and much more by simply pressing the Tab key.
Manage aliases
Aliases are shortcuts for the commands you use often. For example, instead of typing ls -la every time you want to list the files of a directory with details, you can create an alias:
alias ll='ls -la'This lets you simply type ll instead of ls -la.
Test the configuration
After making changes to your .zshrc file, you need to reload the configuration to see the changes, by running:
source ~/.zshrcAutocompletion in Zsh
One of the major strengths of Zsh over other shells is its advanced autocompletion system, which goes well beyond what bash offers. Autocompletion in Zsh completes not only file and command names, but also command options, environment variables, directory paths and much more. The examples below show what the Tab key completes once compinit is loaded.
-
Smart command completion:
For example, if you start typing
git chand pressTab, Zsh can suggestgit checkoutorgit cherry-pick, depending on what is most likely in the context. -
Command option completion:
Zsh is not limited to completing command names. It can also complete the specific options of commands. For example, if you type
ls --and pressTab, Zsh shows a list of every possible option of thelscommand, such as--all,--human-readable, etc. -
File and directory name completion:
Zsh excels at completing file and directory paths. If you start typing a path, Zsh can automatically complete the file or directory name according to the current context. For example, if you type
cd /uand pressTab, Zsh can complete/usr/if it is the only matching directory. -
Environment variable completion:
When you type a command that uses an environment variable, Zsh can complete the variable name for you. For example, if you type
echo $Pand pressTab, Zsh can complete with$PATHor any other environment variable starting withP. -
Contextual autocompletion:
Zsh can provide contextual completions, which means it can adjust its suggestions to the situation. For example, if you use the ssh command, Zsh can complete the known host names from the
~/.ssh/known_hostsfile. -
Command argument autocompletion:
Some commands accept specific arguments and Zsh can complete them too. For example, if you use
killto stop a process, Zsh can complete with the PIDs of the running processes.
Navigating in the terminal
Zsh offers many options to improve navigation in the terminal, making your experience smoother and more efficient. Whether you move from one directory to another, search commands in your history, or want to quickly fix a typo, Zsh has powerful tools to help you, presented below.
Navigating the command history
One of the most practical features of Zsh is the advanced management of the command history. Zsh lets you quickly find and run again commands you typed earlier.
- Search the history with
Ctrl + RYou can search the command history by pressingCtrl + R. This key combination opens an incremental search in the history. Start typing part of the command you are looking for and Zsh shows the most recent command matching your input.- Example: If you previously ran
git push origin mainand you typegit, Zsh suggests that command. You can then pressEnterto run it again or the arrows to move through the other matching commands.
- Example: If you previously ran
- Navigate the history with the arrows You can also use the
↑and↓arrows to go through the previous commands. Zsh remembers every command you ran in your session and lets you go through them quickly.
Changing directory quickly
Moving between directories is a daily task for every Zsh user. Fortunately, Zsh offers several ways to speed up this navigation.
-
Using
cdand completion The simplest way to change directory is to use thecdcommand, followed by part of the path, then press theTabkey. Zsh automatically completes the rest of the path if it is unique, or offers options if several possibilities exist.- Example: Type
cd /uand pressTab. If/usr/is the only matching directory, Zsh completes it for you.
- Example: Type
-
Back to the previous directory with
cd -You can quickly go back to the last directory you were in withcd -. This command is particularly useful when you work between two directories.- Example: If you are in
/home/user/projectsand you change directory to/etc, typingcd -takes you instantly back to/home/user/projects.
- Example: If you are in
Keyboard shortcuts on the command line
When you type a long command with several arguments, it can be tedious to go back to change a specific part. Zsh offers shortcuts to move quickly on a command line. Most are those of Bash, but not all: measured with bindkey, Ctrl + U erases the whole line under Zsh (kill-whole-line), where Bash only erases what comes before the cursor. The cut text goes to the shell's own cut buffer (the kill ring), not to the system clipboard:
Ctrl + AorCmd + ←: Moves the cursor to the start of the line.Ctrl + EorCmd + →: Moves the cursor to the end of the line.Alt + BorOption + ←: Moves the cursor one word back.Alt + ForOption + →: Moves the cursor one word forward.Ctrl + B: Moves the cursor one character back (like the left arrow).Ctrl + F: Moves the cursor one character forward (like the right arrow).Ctrl + U: Cuts the whole line, wherever the cursor is (under Bash: only what comes before the cursor).Ctrl + K: Cuts everything after the cursor on the command line.Ctrl + W: Deletes the word just before the cursor.Ctrl + Y: Pastes the text previously cut withCtrl + U,Ctrl + K, orCtrl + W.Ctrl + L: Clears the screen and puts the cursor back at the top, like theclearcommand.Ctrl + T: Swaps the character under the cursor with the one before it (transpose-chars).
Customising with Oh My Zsh
One of the main reasons why Zsh is so popular is how easily it can be customised. Oh My Zsh is an open source framework that makes this customisation easier by offering simplified management of themes and plugins. The following sections cover its installation, the choice of a theme and the addition of plugins.

Installing Oh My Zsh
Oh My Zsh offers a one-command installation through sh -c "$(curl ...)", but running a remote script without reading it is a bad security habit. Prefer to download it, inspect it, then run it:
# 1. Download the installation scriptcurl -fsSLo install-omz.sh https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh# 2. Read it before running itless install-omz.sh# 3. Run it once its content suits yoush install-omz.shThe script downloads Oh My Zsh then configures Zsh to use it.
Once the installation is done, Oh My Zsh automatically replaces your current .zshrc file with a new basic file, while backing up the old one as .zshrc.pre-oh-my-zsh.
Using themes
One of the advantages of Oh My Zsh is how easily you can change the theme of your prompt. Oh My Zsh comes with a variety of preinstalled themes, each changing the look of your prompt.
To change theme, change the ZSH_THEME variable in your .zshrc file. For example, to use the agnoster theme, open your .zshrc file in a text editor and change the matching line:
ZSH_THEME="agnoster"After changing the theme, reload your .zshrc file to apply the changes:
source ~/.zshrcHere are a few popular themes included with Oh My Zsh:
- robbyrussell (the default theme): a simple and clean theme.
- agnoster: a very popular theme, especially when used with fonts supporting powerline icons.
You can see all the available themes here.
Adding and managing plugins
Oh My Zsh also makes it easy to add plugins that extend the features of Zsh. These plugins can improve automatic completion, add shortcuts for frequently used commands, and much more.
Plugins are defined in the .zshrc file, in the plugins section. For example, to turn on the git and zsh-autosuggestions plugins, change the following line in your .zshrc:
plugins=(git zsh-autosuggestions)After having added or changed plugins, reload your .zshrc file to apply the changes:
source ~/.zshrcPopular plugins
Here are a few popular plugins you can consider turning on, all shipped with Oh My Zsh and turned on by their name in plugins=( ):
- git: adds many handy commands to work with Git.
- zsh-syntax-highlighting: adds syntax highlighting in the terminal to make commands easier to read.
- zsh-autosuggestions: shows command suggestions from your history as you start typing a command.
- docker: adds shortcuts and completions to work with Docker.
Advanced customisation with .oh-my-zsh/custom
If you want to go even further in customisation, Oh My Zsh lets you add custom scripts, themes and plugins in the ~/.oh-my-zsh/custom directory. This lets you customise your environment without touching the main configuration files, which is particularly useful during updates of Oh My Zsh.
The Powerlevel10k theme
Powerlevel10k is a theme for Zsh that radically transforms the look and features of your prompt, with particular care for display speed.

Advanced features of Powerlevel10k
Powerlevel10k also offers advanced features for users who want even more customisation:
- Conditional prompt: show or hide prompt segments depending on specific conditions, such as the state of a Git repository or the type of machine.
- Dynamic prompt: automatically shorten the prompt when space is limited, by removing or simplifying some segments.
- Integration with third-party tools: Powerlevel10k can integrate with other tools and environments, such as Python or Node.js environments, to show contextual information in the prompt.
Installing specific fonts with Powerlevel10k
To make the most of the icons and special symbols of Powerlevel10k, it is recommended to use a compatible font such as MesloLGS NF, optimised for terminals with extra characters. Here is how to install that font:
- Download and install the MesloLGS NF font: you can download the font directly from the Powerlevel10k GitHub repository: MesloLGS NF Open the downloaded file and click "Install font".
- Configure the terminal to use the new font:
- Open the preferences of your Terminal.
- Change the font by selecting MesloLGS NF.
Installing Powerlevel10k
Installing Powerlevel10k is simple and can be done in several ways. If you use Oh My Zsh, here is how to install it:
-
Clone the Powerlevel10k repository into the Oh My Zsh themes directory:
Terminal window git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k -
Configure Oh My Zsh to use Powerlevel10k as its theme:
Open your
.zshrcfile in a text editor and change the line defining the theme:Terminal window ZSH_THEME="powerlevel10k/powerlevel10k" -
Reload your
.zshrcfile to apply the changes:Terminal window source ~/.zshrc
Initial configuration of Powerlevel10k
Once Powerlevel10k is installed, it starts automatically with a configuration wizard on the first start. This wizard guides you through several options to customise the look of your prompt.
-
Starting the configuration wizard:
If the wizard does not start automatically, you can run it by hand with the command:
Terminal window p10k configure -
Customisation options:
The wizard asks you to choose options such as:
- Prompt style: minimalist, classic, or with information-rich segments.
- Icons and symbols: choose whether you want to use special icons and symbols (requires a compatible font).
- Status indicators: turn on or off the status indicators for elements such as the state of the Git repository, the state of previous commands, etc.
- Colours and styles: choose among different colour palettes and styles to match your visual preferences.
Manual customisation of Powerlevel10k
Although the configuration wizard offers great flexibility, you can also customise Powerlevel10k by hand by editing the generated configuration file .p10k.zsh. This file holds all the configuration options you selected, as well as extra variables you can adjust to refine your prompt further.
-
Opening the
.p10k.zshfile:You can open this file with a text editor to make changes to it:
Terminal window nano ~/.p10k.zsh -
Customising the prompt segments:
Powerlevel10k organises the prompt into segments, each representing a specific piece of information such as the user name, the host, the current directory, the Git state, etc. You can turn on, turn off, or reorder these segments by changing the matching lines in
.p10k.zsh.-
Example: To add or remove the display of the user, find the following line:
Terminal window typeset -g POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(context dir vcs)Here,
contextrepresents the user and the host. You can remove it from the list if you do not want to show this information.
-
-
Changing colours and icons:
Each prompt segment can be customised with specific colours and icons. For example, to change the colour of the current directory, change the following variable:
Terminal window typeset -g POWERLEVEL9K_DIR_FOREGROUND=39You can also customise the icons by changing variables such as
POWERLEVEL9K_DIR_ICON.
Creating and using custom functions
Zsh lets you create custom functions, reusable blocks of code that can run a series of commands. Functions are extremely useful to automate repetitive tasks, simplify complex commands, or add specific features to your working environment. They are declared in the .zshrc file, with a syntax identical to Bash's.
Creating a basic function
A Zsh function is defined with the following syntax, the name followed by parentheses and a block between braces:
function_name() { # Code to run}For example, suppose you want to create a function that quickly creates a new directory and moves into it. You can define it as follows:
mkcd() { mkdir -p "$1" cd "$1"}With this function, you can simply type mkcd folder_name to create a new directory and enter it immediately.
Using parameters in a function
Functions can also accept parameters, which makes them more flexible. In the previous example, $1 refers to the first argument passed to the function (in this case, the name of the directory).
Here is another example where a function takes several arguments. Suppose you want to create a function that archives a folder:
backup() { local source_dir="$1" local backup_dir="$2" tar -czvf "${backup_dir}/$(basename "$source_dir")_backup_$(date +%Y%m%d).tar.gz" "$source_dir"}This backup function takes two arguments: the directory to back up (source_dir) and the destination directory (backup_dir). It creates a tar.gz archive of the source directory and places it in the backup directory with a file name including the date.
Functions with conditional logic
Functions can also include conditions and loops, which lets you create more sophisticated scripts directly in your Zsh. Here is an example of a function that checks that a file exists before deleting it:
safe_remove() { if [ -f "$1" ]; then rm "$1" echo "$1 has been deleted." else echo "Error: $1 does not exist." fi}With this function, you can be sure that the file exists before trying to delete it, thus avoiding errors.
Managing functions in .zshrc
Custom functions are usually added directly to your .zshrc file, which makes them available every time you open a new terminal. To add a function, simply open your .zshrc file with a text editor:
nano ~/.zshrcThen add the definition of your function at the end of the file or in a dedicated section. For example:
# Custom functionsmkcd() { mkdir -p "$1" cd "$1"}
backup() { local source_dir="$1" local backup_dir="$2" tar -czvf "${backup_dir}/$(basename "$source_dir")_backup_$(date +%Y%m%d).tar.gz" "$source_dir"}
safe_remove() { if [ -f "$1" ]; then rm "$1" echo "$1 has been deleted." else echo "Error: $1 does not exist." fi}Reloading and testing your functions
After adding your functions, remember to reload your .zshrc file so that the changes are taken into account:
source ~/.zshrcYou can now use your functions in the terminal like any other command.
Advanced organisation: separate files
If you have many functions or complex ones, you can organise them in separate files to keep a .zshrc that is clean and easy to manage. For example, you can create a ~/.zsh_functions file to store all your functions:
-
Create a file for your functions:
Terminal window touch ~/.zsh_functions -
Move your functions into this file.
-
In your
.zshrc, source this file to load the functions at startup:Terminal window source ~/.zsh_functions
Recommendations to go further
Although this guide covers the basics and a few advanced aspects of Zsh, there is still a lot to explore. Here are a few recommendations to deepen your mastery of Zsh:
- Explore more plugins: Zsh has many plugins beyond those mentioned in this guide. Visit the Oh My Zsh Plugins repository to discover other plugins that could match your specific needs.
- Automate your daily tasks: use Zsh functions and scripts to automate repetitive tasks. This can include deployment scripts, file management, or integration with other tools such as Docker or Kubernetes.
- Stay up to date with new versions of Zsh: Zsh keeps evolving, with new features and bug fixes. Make sure you keep your Zsh installation up to date to benefit from the latest improvements.
Troubleshooting
The most frequent blockers concern the change of shell, the first start and the slowness of an overloaded .zshrc. The chsh messages and the first-start menu were captured on Debian 13 and AlmaLinux 10.
| Symptom | Likely cause | Solution |
|---|---|---|
chsh: PAM: Authentication failure | Wrong password typed | Run chsh again with your account's password |
chsh refuses the path of Zsh | Path missing from /etc/shells (installation outside the package) | Add it: command -v zsh | sudo tee -a /etc/shells |
| The zsh-newuser-install menu comes back at every start | No startup file in the home directory (Debian, Ubuntu) | Create ~/.zshrc, even empty |
| Oh My Zsh does not load the plugins | The plugin is not listed in plugins=(...) of .zshrc | Add the plugin name to the plugins variable and run source ~/.zshrc again |
| The terminal is very slow to start | Too many plugins loaded or a heavy theme | Reduce the number of plugins and profile with zprof: add zmodload zsh/zprof at the top of .zshrc |
| The special characters of the prompt do not show | Font without Nerd Font glyphs | Install a Nerd Font (e.g. MesloLGS NF) and configure it in the terminal |
History of Zsh
Zsh was created in 1990 by Paul Falstad, with the aim of combining the best features of the shells of the time, such as bash, ksh and tcsh, while adding new features.
Over the years, Zsh gradually gained popularity thanks to its flexibility and advanced capabilities. At first, it was mostly used by a handful of experienced users looking for more features than traditional shells could offer. Over time, developers and system administrators started to adopt Zsh for its ability to improve productivity on the command line.
A turning point for the popularity of Zsh was the introduction of Oh My Zsh in 2009, a framework that greatly simplified configuration management, adding plugins and customising the shell. Thanks to Oh My Zsh, even less technical users could easily access the powerful features of Zsh.
Zsh became the default shell of macOS with Catalina (version 10.15, 2019), which put it in the hands of every Mac user. On Linux, it remains a personal choice: none of the three reference distributions installs it or turns it on by default.
Key points
- Zsh is compatible with most Bash scripts while offering better autocompletion and navigation.
- Oh My Zsh radically simplifies configuration with its ready-to-use themes and plugins.
- Powerlevel10k offers a fast, informative prompt, but the project now only has very limited support.
- Custom functions in
.zshrclet you automate repetitive tasks. chsh -s $(which zsh)sets Zsh as the default shell permanently.
Knowledge check
Check that the essentials of this guide stuck. The questions cover only what has just been explained here.
Knowledge check
Check what you have learned with this interactive quiz
How it works
- The timer starts when you click Start
- Multiple choice, true/false and short answer questions
- You can move between questions
- Detailed results are shown at the end
Starts the quiz and the timer
Review
(0/0)Score by domain
A domain groups several guides and gets several questions, so its score is more reliable than a per-topic score, which often rests on a single question.
Summary
Strengths
No topic passed at 80% on at least two questions yet.
Weak areas
No topic below the pass mark.
Recommended next
Hints before you try again?
Continue the course: Fish shell: install and configure config.fish
A new full quiz with random questions
Work again only on the questions you missed