zsh and Oh My Zsh on Linux: Complete Setup Guide

Tested on: Ubuntu 26.04 LTS · Debian 12 · Fedora 44 · Arch Linux · macOS Sequoia — Last updated: June 2026
Zsh (Z Shell) is a POSIX-compatible shell that improves on Bash with better tab completion, recursive globbing, spell correction, and a more powerful history system. Oh My Zsh wraps it in a plugin and theme framework that turns a competent shell into a genuinely productive environment. This guide covers installation, configuration, essential plugins, the Powerlevel10k prompt, and fzf integration — everything you need to go from a stock Bash prompt to a fully tuned zsh setup.
Prerequisites
- A Linux system or macOS with terminal access (macOS ships with zsh already installed)
curlorwgetandgitinstalled- A terminal emulator that supports 256 colors — most modern ones do (GNOME Terminal, Kitty, Alacritty, iTerm2, WezTerm)
- For Powerlevel10k: a Nerd Font installed and set in your terminal preferences
Install zsh
macOS Sequoia ships zsh as the default — skip ahead to setting it as default. On Linux, install from your package manager:
# Ubuntu / Debian:
sudo apt install zsh git curl
# Fedora:
sudo dnf install zsh git curl
# Arch Linux:
sudo pacman -S zsh git curl
# openSUSE:
sudo zypper install zsh git curl
# Verify the version:
zsh --versionExpected output:
zsh 5.9 (x86_64-ubuntu-linux-gnu)Set zsh as Your Default Shell
# List shells available on your system:
cat /etc/shells
# Change default shell for your user:
chsh -s $(which zsh)
# Log out and back in, then verify:
echo $SHELLExpected output after re-login:
/usr/bin/zshIf chsh is unavailable or restricted (some corporate or containerized environments), add this to your ~/.bash_profile as a workaround:
echo 'exec zsh' >> ~/.bash_profileThe first time you launch zsh without an existing ~/.zshrc, it opens a configuration wizard. Press q to exit it — Oh My Zsh will generate a proper config file for you in the next step.
What zsh Adds Over Bash
Before reaching for Oh My Zsh, it's worth understanding what raw zsh gives you — these features work without any framework.
Interactive Tab Completion
Enable the completion system in ~/.zshrc (Oh My Zsh does this automatically, but here's what it looks like manually):
autoload -Uz compinit && compinitWith this active, pressing Tab after git shows a navigable menu of subcommands with descriptions. Pressing Tab after kill shows running processes. Arrow keys move through the menu; Enter selects.
Recursive Globbing
# Find all Python files in the current tree — no find or fd needed:
ls **/*.py
# Files modified within the last day:
ls -la *(m-1)
# Files larger than 1 MB:
ls -la *(Lm+1)
# Directories only:
ls -d **/Spell Correction and Helpful Options
# Add to ~/.zshrc:
setopt CORRECT # suggest corrections for mistyped commands
setopt AUTO_CD # type a directory name to cd into it
setopt EXTENDED_GLOB # enables extended globbing patternsWith CORRECT enabled, typing pyhon3 script.py produces:
zsh: correct 'pyhon3' to 'python3' [nyae]?# Add to ~/.zshrc:
setopt SHARE_HISTORY # sync history across all open terminals
setopt HIST_IGNORE_DUPS # skip duplicate consecutive commands
setopt HIST_IGNORE_SPACE # skip commands prefixed with a space
setopt HIST_VERIFY # show expanded history command before running
HISTSIZE=50000
SAVEHIST=50000
HISTFILE=~/.zsh_historyThe space-prefix trick is particularly useful: prepend any command with a space and it won't appear in history — good for commands containing credentials.
Install Oh My Zsh
Oh My Zsh manages your zsh configuration, bundling 300+ plugins and 150+ themes. The installer backs up your existing ~/.zshrc, creates ~/.oh-my-zsh/, writes a fresh config, and sets zsh as your default shell if it isn't already.
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"The installer output ends with something like:
__ __
____ / /_ ____ ___ __ __ ____ _____/ /_
/ __ / __ / __ `__ / / / / /_ / / ___/ __
/ /_/ / / / / / / / / / / /_/ / / /_(__ ) / / /
____/_/ /_/ /_/ /_/ /_/__, / /___/____/_/ /_/
/____/
....is now installed!
Before you scream "Oh My Zsh!" please look over the ~/.zshrc file to select plugins, themes, and options.To update Oh My Zsh at any time:
omz updateEssential Plugins
Plugins are enabled in the plugins=() array in ~/.zshrc. Order matters for the two syntax-related plugins — zsh-syntax-highlighting must be last.
Built-in Plugins
These ship with Oh My Zsh inside ~/.oh-my-zsh/plugins/. Enable them by name — no installation needed:
plugins=(
git # git aliases (gst, gco, gcmsg, gp, gl, etc.) and branch in prompt
docker # docker and docker-compose completions and aliases
kubectl # kubernetes completion + kube-context in prompt
python # aliases: py=python3, pip=pip3, pyclean, etc.
systemd # aliases: sc-start, sc-stop, sc-status, sc-restart
sudo # press Esc twice to prepend sudo to the current/last command
z # tracks directory visits; type 'z proj' to jump to ~/work/myproject
history # h = history, hsi = grep history, hsl = last 20
colored-man-pages # colorizes man page output — genuinely useful
extract # 'extract archive.tar.gz' works on any archive format
)The sudo plugin deserves special mention: if you run a command and get a permission error, just double-tap Escape and zsh prepends sudo. No retyping.
Third-Party Plugins (Install Manually)
These two are non-negotiable — install them regardless of anything else:
# zsh-autosuggestions: shows command suggestions in grey as you type
# Accept with → (right arrow) or Ctrl+E
git clone https://github.com/zsh-users/zsh-autosuggestions
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
# zsh-syntax-highlighting: colors valid commands green, invalid ones red
# Catches typos before you hit Enter
git clone https://github.com/zsh-users/zsh-syntax-highlighting
${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlightingAdd them to your plugins list — syntax-highlighting goes last:
plugins=(
git
sudo
z
history
colored-man-pages
extract
docker
kubectl
zsh-autosuggestions
zsh-syntax-highlighting
)Then reload:
source ~/.zshrcPowerlevel10k — The Best Prompt
Powerlevel10k is the de facto standard zsh prompt. It renders asynchronously (the prompt never waits on slow operations like git status queries), is extremely configurable, and ships an interactive setup wizard.
Step 1: Install a Nerd Font
Powerlevel10k uses icons from Nerd Fonts for git symbols, directory separators, and status indicators. MesloLGS NF is the recommended choice:
mkdir -p ~/.local/share/fonts && cd ~/.local/share/fonts
# Download the four MesloLGS NF variants:
wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf
wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf
wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf
wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf
# Rebuild font cache:
fc-cache -f
# Then go to your terminal's font settings and select "MesloLGS NF"Step 2: Install Powerlevel10k
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git
${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10kSet the theme in ~/.zshrc:
ZSH_THEME="powerlevel10k/powerlevel10k"Reload and the configuration wizard starts automatically:
source ~/.zshrcThe wizard asks a series of visual questions to detect font support and walks through style preferences: prompt shape (lean, classic, rainbow, pure), whether to show the current time, how to display git status, and what information segments to include. The output is written to ~/.p10k.zsh. Re-run the wizard anytime:
p10k configureA configured p10k prompt shows: working directory (with intelligent path shortening), git branch, git status (staged/unstaged/untracked), Python virtualenv, kubectl context, last command exit code, and execution time for commands that took more than a threshold (default 3s). All of this updates without blocking your prompt.
The ~/.zshrc Structure
After Oh My Zsh and Powerlevel10k are set up, a clean ~/.zshrc looks like this:
# ~/.zshrc
# Powerlevel10k instant prompt — must be at the very top:
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
# Oh My Zsh installation path:
export ZSH="$HOME/.oh-my-zsh"
# Theme:
ZSH_THEME="powerlevel10k/powerlevel10k"
# Plugins:
plugins=(
git sudo z history colored-man-pages extract
docker kubectl
zsh-autosuggestions
zsh-syntax-highlighting
)
# Load Oh My Zsh:
source $ZSH/oh-my-zsh.sh
# ── Your customizations below this line ──────────────────────────
# History settings:
setopt SHARE_HISTORY
setopt HIST_IGNORE_DUPS
setopt HIST_IGNORE_SPACE
HISTSIZE=50000
SAVEHIST=50000
# Aliases:
alias ll='ls -alF'
alias ..='cd ..'
alias ...='cd ../..'
alias gs='git status'
alias gl='git log --oneline --graph --decorate'
alias ports='ss -tulpn'
alias myip='curl -s ifconfig.me'
# Functions:
mkcd() { mkdir -p "$1" && cd "$1"; }
# Load Powerlevel10k config:
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zshfzf — Fuzzy Finder Integration
fzf is a fast interactive filter for any list-based operation. Integrated with zsh, it replaces the default Ctrl+R history search with a full-screen fuzzy finder and adds fuzzy file and directory pickers.
# Install:
sudo apt install fzf # Ubuntu / Debian
sudo dnf install fzf # Fedora
sudo pacman -S fzf # Arch
# Enable zsh key bindings and completion:
# Ubuntu/Debian — source from the package's included files:
echo 'source /usr/share/doc/fzf/examples/key-bindings.zsh' >> ~/.zshrc
echo 'source /usr/share/doc/fzf/examples/
