$linuxjunkies
>

Modern Replacements: bat, eza, zoxide

Replace cat, ls, and cd with bat, eza, and zoxide for syntax highlighting, richer file listings, and instant directory jumping — with safe shell aliases.

BeginnerUbuntuDebianFedoraArch7 min readUpdated June 7, 2026

Before you start

  • A working terminal with bash, zsh, or fish
  • sudo or root access to install packages
  • curl installed (for zoxide fallback install script)
  • Basic familiarity with editing shell RC files (~/.bashrc or ~/.zshrc)

The classic Unix tools cat, ls, and cd work fine, but bat, eza, and zoxide make daily terminal work noticeably faster and more readable. This guide walks through installing all three, validating they work, and wiring up safe aliases so you keep backward compatibility.

What You Are Replacing and Why

  • bat replaces cat: syntax highlighting, line numbers, Git change markers, and automatic paging for long files.
  • eza replaces ls: colour-coded output, Git status column, icon support, better tree mode. Eza is the actively maintained fork of the now-archived exa.
  • zoxide replaces cd: remembers your most-visited directories and lets you jump to them with a short fuzzy substring instead of a full path.

None of these break existing scripts. Aliases only affect your interactive shell; scripts that call /bin/ls, /bin/cat, or use cd as a built-in are unaffected as long as you alias carefully.

Installing bat

Debian / Ubuntu

The package has been in Debian since Bullseye and Ubuntu since 20.04, but the package name collides with another tool on older releases, so confirm what you get:

sudo apt install bat

On Ubuntu 20.04 and some Debian versions the binary is installed as batcat, not bat, to avoid the name clash. Check with:

which bat || which batcat

If you only have batcat, add a personal symlink so the alias below works uniformly:

mkdir -p ~/.local/bin
ln -s "$(which batcat)" ~/.local/bin/bat

Make sure ~/.local/bin is on your PATH (it usually is on modern Ubuntu; if not, add export PATH="$HOME/.local/bin:$PATH" to your shell RC).

Fedora / RHEL 9+ / Rocky 9+

sudo dnf install bat

Arch Linux

sudo pacman -S bat

Installing eza

Eza is newer than exa and is not yet in all default repositories. Check first; fall back to the official release tarball if needed.

Debian / Ubuntu (22.04+)

Eza maintains an official apt repository:

sudo apt install -y gpg
wget -qO- https://raw.githubusercontent.com/eza-community/eza/main/deb.asc \
  | sudo gpg --dearmor -o /etc/apt/keyrings/eza.gpg
echo "deb [signed-by=/etc/apt/keyrings/eza.gpg] http://deb.gierens.de stable main" \
  | sudo tee /etc/apt/sources.list.d/eza.list
sudo apt update
sudo apt install eza

Fedora

sudo dnf install eza

Arch Linux

sudo pacman -S eza

Icon support (optional)

Eza can show file-type icons with --icons, but only if your terminal uses a Nerd Font. Install one from nerdfonts.com and set it in your terminal emulator. Without a Nerd Font the flag still works but outputs garbled characters.

Installing zoxide

Debian / Ubuntu

sudo apt install zoxide

If the package is too old or absent, use the upstream installer script (it places a static binary in ~/.local/bin):

curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh

Fedora / RHEL / Rocky

sudo dnf install zoxide

Arch Linux

sudo pacman -S zoxide

Shell initialisation — required step

Zoxide needs a hook in your shell to record every directory you visit. Add the appropriate line to your shell RC file, then reload it.

bash — add to ~/.bashrc:

eval "$(zoxide init bash)"

zsh — add to ~/.zshrc:

eval "$(zoxide init zsh)"

fish — add to ~/.config/fish/config.fish:

zoxide init fish | source

After editing, reload:

source ~/.bashrc   # or ~/.zshrc

Setting Up Safe Aliases

Aliases below override the default commands in interactive sessions only. They include fallback guards so your shell does not break if a tool is temporarily absent.

Add the following block to ~/.bashrc (or ~/.zshrc), after the zoxide init line:

# bat — syntax-highlighted cat
if command -v bat >/dev/null 2>&1; then
  alias cat='bat --paging=never'
  alias less='bat'
elif command -v batcat >/dev/null 2>&1; then
  alias cat='batcat --paging=never'
  alias less='batcat'
fi

# eza — modern ls
if command -v eza >/dev/null 2>&1; then
  alias ls='eza --group-directories-first'
  alias ll='eza -lh --group-directories-first --git'
  alias la='eza -lah --group-directories-first --git'
  alias lt='eza --tree --level=2'
fi

# zoxide — smarter cd
# 'z' is the zoxide jump command added by init above.
# Optionally shadow 'cd' itself — only do this if you are comfortable:
# alias cd='z'

The cd='z' alias is commented out deliberately. Zoxide's z command does not handle some edge cases that cd handles (such as cd - for going back, or bare cd to go home) equally well in all shells. Use z as a complement rather than a full replacement until you are confident. In bash and zsh, cd - and cd alone still work normally alongside z.

Verifying the Setup

Open a new terminal (or run source ~/.bashrc) and run a quick sanity check:

# bat
bat --version
cat /etc/os-release       # should show highlighted output

# eza
eza --version
ls /etc                   # colour, grouped directories
ll /usr/bin               # long format with git column
lt /etc                   # tree, 2 levels deep

# zoxide — visit a few dirs first so it learns them
cd ~/Downloads && cd ~/Documents && cd /tmp
z Down                    # should jump to ~/Downloads
pwd                       # confirm

Expected z Down output: your shell prompt moves to /home/yourname/Downloads. The first time you use zoxide it needs a few visits before the ranking is meaningful.

Useful Flags to Know

ToolFlagEffect
bat-nLine numbers only, no syntax theme
bat--plainRaw output, useful in pipes
bat-l jsonForce JSON highlighting on extensionless files
eza--iconsFile-type icons (needs Nerd Font)
eza--gitShow Git status per file
eza--color=neverPipe-safe plain output
zoxideziInteractive fuzzy picker (requires fzf)
zoxidezoxide query -lList all remembered directories by score

Troubleshooting

  • bat shows no colour in pipes: bat detects pipe context and strips colour. Force it with bat --color=always when piping to another tool like grep.
  • eza says "unknown flag --icons": You have the old exa package installed, not eza. Confirm with eza --version; the output should say eza. Remove exa and reinstall.
  • zoxide does not jump anywhere: The init line is missing or the shell was not reloaded. Run type z; if it returns "not found", re-check your RC file and reload.
  • zi (interactive mode) errors: zi requires fzf. Install it with your package manager (apt install fzf, dnf install fzf, pacman -S fzf).
  • Aliases break a script: Scripts use their own non-interactive shell and do not load your ~/.bashrc aliases. If a script breaks, it was calling the command by name without a full path and you've changed something else — aliases are not the cause.
tested on:Ubuntu 24.04Debian 12Fedora 40Arch rolling

Frequently asked questions

Will aliasing cat to bat break shell scripts?
No. Shell aliases only apply in interactive sessions. Scripts run in a non-interactive subshell that does not source ~/.bashrc aliases, so /bin/cat is always called directly.
Is eza the same as exa?
No. Exa is archived and no longer maintained. Eza is a community fork that continues active development. If your package manager installs exa, check for an eza package or add the official eza repository.
How does zoxide decide which directory to jump to?
Zoxide scores directories by a combination of how frequently and how recently you have visited them (a frecency algorithm). The highest-scoring match for your query is selected.
Can I use these tools over SSH without reinstalling them on every server?
You need them installed on the remote host for remote sessions. However, you can keep a personal ~/.local/bin with statically compiled binaries and rsync that directory to remote machines you manage regularly.
bat seems slow on very large files — what should I do?
Use bat --paging=always for large files so it pages through them, or use --plain to skip syntax highlighting entirely. For files over a few megabytes, piping to plain less is still the faster option.

Related guides