Zsh Shell

Zsh cheatsheet — interactive shell with advanced completion and scripting. .zshrc setup, aliases, plugins, glob patterns, history search, and oh-my-zsh integration.

8 min read

What it is

Zsh is a powerful, interactive shell that extends Bash with many advanced features, making it ideal for everyday command-line use and scripting.

Installation

Linux (Debian/Ubuntu):

sudo apt update
sudo apt install zsh

Linux (Fedora):

sudo dnf install zsh

Linux (Arch Linux):

sudo pacman -S zsh

macOS:

brew install zsh

If brew is not installed: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Windows (using WSL): First, install Windows Subsystem for Linux. Then, inside your WSL distribution (e.g., Ubuntu):

sudo apt update
sudo apt install zsh

Setting Zsh as default shell (Linux/macOS):

chsh -s $(which zsh)

You will need to log out and log back in for the change to take effect.

Core Concepts

  • Prompt: The text displayed before you type commands. Zsh offers highly customizable prompts (often managed by frameworks like Oh My Zsh).
  • Completion: Zsh’s advanced tab-completion system is a major feature, offering context-aware suggestions for commands, arguments, filenames, and more.
  • Aliases: Short-hand names for longer commands.
  • Functions: Reusable blocks of code that can be executed like commands.
  • Globbing: Advanced pattern matching for filenames beyond simple wildcards.
  • Zsh Options: Numerous configuration settings that control shell behavior (setopt, unsetopt).
  • Zsh Plugins/Frameworks: Tools like Oh My Zsh, Prezto, or Antigen help manage Zsh configuration, themes, and plugins, vastly extending its capabilities.

Commands / Usage

Basic Navigation and File Management

  • cd /path/to/directory: Change the current directory.
    • cd ..: Move up one directory.
    • cd ~ or cd: Go to your home directory.
    • cd -: Go to the previous directory.
  • ls: List directory contents.
    • ls -l: Long listing format (permissions, owner, size, date).
    • ls -a: Show all files, including hidden ones (starting with .).
    • ls -lh: Long listing with human-readable file sizes (e.g., 1K, 234M, 2G).
    • ls -lt: List by modification time, newest first.
    • ls -ltr: List by modification time, oldest first.
  • pwd: Print the current working directory.
  • mkdir new_directory: Create a new directory.
    • mkdir -p parent/child/grandchild: Create parent directories as needed.
  • cp source_file destination: Copy files or directories.
    • cp -r source_directory destination: Recursively copy a directory.
    • cp file1 file2 destination_directory/: Copy multiple files into a directory.
  • mv source destination: Move or rename files or directories.
    • mv old_name new_name: Rename a file.
    • mv file.txt ../another_dir/: Move a file to another directory.
  • rm file.txt: Remove files.
    • rm -r directory_name: Recursively remove a directory and its contents (use with extreme caution!).
    • rm -f file.txt: Force removal without prompting.
    • rm -rf directory_name: Force recursive removal (EXTREME CAUTION REQUIRED!).
  • touch new_file.txt: Create an empty file or update its modification timestamp.

Text Processing and Viewing

  • cat file.txt: Concatenate and display file content.
    • cat file1.txt file2.txt > combined.txt: Combine files.
  • less file.txt: View file content page by page (use q to quit, space for next page, b for previous page, / to search).
  • head file.txt: Display the first 10 lines of a file.
    • head -n 20 file.txt: Display the first 20 lines.
  • tail file.txt: Display the last 10 lines of a file.
    • tail -n 50 file.txt: Display the last 50 lines.
    • tail -f logfile.log: Follow the end of a file, showing new lines as they are added (useful for logs).
  • grep "pattern" file.txt: Search for lines matching a pattern.
    • grep -i "pattern" file.txt: Case-insensitive search.
    • grep -v "pattern" file.txt: Invert match (show lines not matching).
    • grep -r "pattern" directory/: Search recursively in a directory.
    • ls -l | grep ".txt": Pipe output of ls to grep.
  • sed 's/old/new/g' file.txt: Stream editor for text transformations (e.g., find and replace).
    • sed -i 's/old/new/g' file.txt: Modify the file in-place.
  • awk '{print $1}' file.txt: Pattern scanning and processing language (useful for column-based data).
    • ls -l | awk '{print $9}': Print the 9th column (filename) from ls -l output.

Process Management

  • ps aux: List all running processes.
  • top: Display dynamic real-time view of running processes.
  • kill PID: Terminate a process by its Process ID (PID).
    • kill -9 PID: Forcefully kill a process.
  • bg: Put a stopped job in the background.
  • fg: Bring a background job to the foreground.
  • jobs: List currently running background jobs.
  • Ctrl+C: Interrupt (send SIGINT) the current foreground process.
  • Ctrl+Z: Suspend (send SIGTSTP) the current foreground process.

Networking

  • curl url: Transfer data from or to a server.
    • curl -O https://example.com/file.zip: Download file.zip.
    • curl -I https://example.com: Fetch HTTP headers only.
    • curl -X POST -d "key=value" https://api.example.com/data: Send a POST request.
  • wget url: Non-interactive network downloader.
    • wget https://example.com/file.zip: Download file.zip.
    • wget -r -np https://example.com/docs/: Recursively download files from a directory.
  • ssh user@hostname: Connect to a remote machine.
    • ssh -p 2222 user@hostname: Connect using a specific port.
  • scp source user@hostname:destination: Securely copy files between hosts.
    • scp file.txt user@remote_host:/path/to/save/: Copy file.txt to remote host.
    • scp user@remote_host:/path/to/file.txt .: Copy file.txt from remote host to current directory.
  • ping hostname: Send ICMP ECHO_REQUEST packets to network hosts.

Zsh Specific Features & Options

  • Tab Completion: Press Tab to complete commands, filenames, arguments, etc.
    • ls **<Tab>: Complete recursively (e.g., ls src/**<Tab>).
    • git ch<Tab>: Complete git checkout.
    • command --<Tab>: List available options/flags for a command.
    • cd /u/s/l<Tab>: Complete /usr/share/local. Zsh intelligently guesses common paths.
  • Globbing:
    • ls *.txt: List all files ending in .txt.
    • ls file?.txt: List file1.txt, fileA.txt, but not file10.txt.
    • ls {dir1,dir2}/file.txt: List dir1/file.txt and dir2/file.txt.
    • ls **/*.log: List all .log files in the current directory and all subdirectories (recursive globbing). Requires setopt globstar.
    • ls *(.): List only regular files.
    • ls @(file1|file2): List file1 or file2.
    • ls ^*.tmp: List files that do not end in .tmp.
  • Aliases:
    • alias ll='ls -lh': Create an alias ll for ls -lh.
    • alias update='sudo apt update && sudo apt upgrade -y': Create an alias for updating packages.
    • unalias ll: Remove an alias.
  • Functions:
    my_backup() {
      cp $1 $1.bak
      echo "$1 backed up to $1.bak"
    }
    # Usage:
    my_backup important_config.txt
    
  • Zsh Options (setopt/unsetopt):
    • setopt auto_cd: If a typed command is a directory name, cd into it automatically.
    • setopt correct: Automatically correct command typos.
    • setopt globstar: Enable ** for recursive globbing.
    • setopt extended_glob: Enable extended globbing features (like *(.), @(), ^).
    • setopt hist_ignore_dups: Don’t store duplicate commands in history.
    • setopt hist_ignore_space: Don’t store commands starting with a space in history.
    • setopt inc_append_history: Write commands to history file immediately.
    • setopt share_history: Share history across all running shells.
    • setopt cdable_vars: Allows cd to a directory whose name is stored in a variable.
    • setopt prompt_subst: Allows parameter expansion, command substitution, etc., in the prompt.
    • setopt NO_BEEP: Disable terminal bell sounds.
    • setopt CLOBBER: Allow output redirection (>) to overwrite existing files (default is often noclobber which prevents overwriting).
    • unsetopt noclobber: Enable overwriting files with >.

History Manipulation

  • history: Display command history.
  • !n: Execute the nth command from history.
  • !!: Execute the last command.
  • !string: Execute the most recent command starting with string.
  • !?string?: Execute the most recent command containing string.
  • Ctrl+R: Reverse incremental search through history. Type part of a command to find it. Press Ctrl+R again to cycle through matches. Press Enter to execute, or arrow keys to edit.
  • fc: Edit and re-execute a previous command.
    • fc: Edit the last command in your default editor.
    • fc -n: Edit the last command without line numbers.
    • fc 100: Edit command number 100.

Common Patterns

  • Recursive Search and Replace:
    # Find all .js files and replace 'oldFunction' with 'newFunction'
    setopt globstar # Ensure recursive globbing is enabled
    for f in **/*.js; do
      sed -i 's/oldFunction/newFunction/g' "$f"
    done
    
  • Finding Large Files:
    du -ah . | sort -rh | head -n 10
    
    (Disk Usage, human-readable, sorted reverse numerically, top 10)
  • Monitoring Log Files:
    tail -f /var/log/syslog | grep --line-buffered "error"
    
    (--line-buffered is crucial for grep when piping to ensure it outputs lines immediately)
  • Cleaning Up Temporary Files:
    find /tmp -type f -mtime +7 -delete
    
    (Delete files in /tmp older than 7 days)
  • Quickly Editing a Configuration File:
    alias vimrc='vim ~/.zshrc'
    vimrc # Opens your zsh config in vim
    
  • Executing a Command on Multiple Files:
    # Using zsh's extended globbing
    setopt extended_glob
    ls *.jpg(.N) | xargs -I {} convert {} -resize 50% processed_{}
    # The `(.N)` part means: only regular files (`.`), if no files match (`N` - nullglob option) do nothing.
    
  • Running a Command in the Background:
    long_running_command &
    # Example:
    sleep 60 &
    
  • Saving Command Output to a File:
    ls -l > file_list.txt
    # To append instead of overwrite:
    ls -l >> file_list.txt
    
  • Combining Commands (using && and ||):
    # Run command2 only if command1 succeeds
    command1 && command2
    
    # Run command2 only if command1 fails
    command1 || command2
    
    # Example: Compile and run if compilation is successful
    gcc my_program.c -o my_program && ./my_program
    

Gotchas

  • rm -rf Danger: This command is extremely powerful and can delete anything without confirmation. Double-check paths before executing.
  • noclobber vs clobber: By default, Zsh might prevent overwriting files with >. If you frequently want to overwrite, use setopt clobber or unsetopt noclobber. Be cautious when changing this.
  • Globbing Behavior: Extended globbing features (*(.), **, etc.) require setopt extended_glob and setopt globstar. If they don’t work, check your options.
  • Zsh vs. Bash Syntax: While largely compatible, some Zsh features (like advanced globbing or array handling) differ from Bash. Scripts intended for Bash might need adjustments.
  • Oh My Zsh Overrides: If you use Oh My Zsh or similar frameworks, many Zsh behaviors (like prompt customization, aliases, and plugins) are managed by the framework, not directly by your .zshrc. Changes might need to be made within the framework’s configuration files.
  • Completion Cache: Sometimes completions might seem stale. You can often force a refresh, though it’s usually automatic.
  • cd after setopt auto_cd: If auto_cd is enabled, typing just a directory name will cd into it. This can be surprising if you intended to run a command whose name happens to be a directory.