Modern Linux Tools Part 7: The Verdict and an Install Script

This is the last part of the Modern Linux Tools series. Over six parts I installed 18 tools on a clean Debian 13 VM and tested each one against the tool it replaces. This part pulls the results together, says which ones I would install everywhere, and gives you a script that installs the lot.

Everything in the series came from the Debian repositories. There is no cargo, no curl | sh and no binary downloaded from GitHub. That was a rule I set at the start, and it shaped what made the list: if a tool is not packaged, it is harder to trust and harder to keep up to date.

The verdicts

ToolReplacesInstall it?The catch
dustduYes, everywhereNone found
dufdfYesSmall convenience
ripgrepgrepYes, everywhereSkips ignored and hidden files, and grep is faster for some single-file searches
deltagit’s pagerYes, everywhereWrites colour codes into pipes
fzfCtrl-RYesA selector, not a grep
tealdeerman (first look)YesNeeds one network update to build the cache
zoxidecdYes, on machines I use dailyOnly knows places you have been
fdfindYes, for interactive useHides ignored and hidden files, slower on a plain glob
trippymtr, tracerouteYes-C is cycles, -c is the config file
gojqjqOptionalSorts keys and rewrites 1.0 as 1
lazygitgit commandsOptionalNo faster for simple jobs
gpingpingOptionalNot for scripts
xhcurlOptionalAbout 4.6x slower to start, reads stdin
ezalsInteractive onlyDecimal sizes, 9x slower recursively, --git-ignore is very slow on large trees
batcatInteractive onlyAbout 80x slower than cat
sdsedOptionalEdits in place by default, same speed
atuin~/.bash_historyOnly if you accept the setupNeeds bash-preexec, secrets filter misses common cases

What I would do

Install everywhere: dust, ripgrep, delta, fzf and tealdeer. These add something without taking anything away. ripgrep is the only one that changes results, and only because it filters files, which is the point of it.

Install on machines I use every day: zoxide, fd, trippy, duf.

Install, but never alias over the old name: eza, bat and sd. The three are nicer to use and each one behaves differently from the tool it replaces. eza shows sizes in powers of 1000, bat is far slower on large files, and sd writes the file without asking. If you alias ls to eza and cat to bat, sooner or later a script will pick up the alias, or you will read a size wrong. Give the new tools their own names or leave the old ones alone.

Skip unless you have a reason: atuin. The interface is the best of the three history tools, but it needs a helper that Debian does not package, and the secrets filter missed three of the five examples I gave it.

The traps, in one list

The same few things came up in several parts. If you only remember one section from the series, make it this one.

  1. Defaults that hide files. rg and fd skip anything in .gitignore and anything hidden. Add -uuu to rg or -HI to fd when a search returns nothing and you expected something.
  2. Defaults that write. sd edits files in place. Put -p on first.
  3. Defaults that change units. eza uses powers of 1000. Add --binary to match ls -h.
  4. Tools that behave differently in a pipe. bat turns its decoration off, rg drops line numbers, xh drops the headers, and delta keeps its colours. Test in a pipe before you put a command in a script.
  5. Benchmarks that cheat. GNU grep stops at the first match when its output goes to /dev/null. Pipe to cat when you time it.
  6. Flags that mean something else. trip -c is a config file, not a cycle count. fd takes a regex, not a glob.
  7. Packages that are not what you expect. yq on Debian is a Python wrapper around jq. fd is fdfind and bat is batcat.

The install script

This installs everything from the series with apt, creates the short names for fd and bat, and builds the tldr cache. It does not touch your shell configuration, because what to enable is a personal choice.

#!/usr/bin/env bash
# Install the apt-packaged tools from the Modern Linux Tools series (Debian 13).
set -euo pipefail

packages=(
  eza fd-find bat du-dust duf        # files
  ripgrep sd                         # search and replace
  zoxide fzf atuin                   # navigation and history
  gping trippy xh mtr-tiny           # network
  jq gojq git-delta lazygit tealdeer # data and git
  hyperfine tmux                     # for testing
)

sudo apt-get update
sudo apt-get install -y "${packages[@]}"

# Debian renames two of the binaries. Create the usual names in ~/.local/bin.
mkdir -p "$HOME/.local/bin"
ln -sf "$(command -v fdfind)" "$HOME/.local/bin/fd"
ln -sf "$(command -v batcat)" "$HOME/.local/bin/bat"

tldr --update
echo "Done. Add ~/.local/bin to PATH if it is not there already."

To test it properly I first purged all 18 packages from the test VM with apt-get purge, deleted the two links and the tldr cache, and checked that none of the commands could be found. Then I ran the script. It exited with status 0, and every command resolved afterwards:

$ for p in eza rg fd bat dust duf sd zoxide fzf atuin gping trip xh jq gojq delta lazygit tldr; do command -v $p; done
/usr/bin/eza
/usr/bin/rg
/home/anon/.local/bin/fd
/home/anon/.local/bin/bat
/usr/bin/dust
/usr/bin/duf
/usr/bin/sd
/usr/bin/zoxide
/usr/bin/fzf
/usr/bin/atuin
/usr/bin/gping
/usr/bin/trip
/usr/bin/xh
/usr/bin/jq
/usr/bin/gojq
/usr/bin/delta
/usr/bin/lazygit
/usr/bin/tldr

The du-dust package installs the binary as dust, so it needs no link. The purge removes packages and not their configuration files, so this was not a brand-new machine, but nothing in the script depends on configuration.

Then add what you want to ~/.bashrc. This is the set I would use:

# Navigation and history
eval "$(zoxide init bash)"
source /usr/share/doc/fzf/examples/key-bindings.bash

# Aliases with their own names, so the originals stay untouched
alias ll='eza -l --binary --git'
alias b='batcat'

And for delta, the block in Part 6 goes in ~/.gitconfig.

What I learned

The tools that won were the ones that change one thing and leave everything else alone: dust answers the same question as du in a better way, and delta makes the same diff easier to read. The tools that need care are the ones that change the rules, such as rg and fd, which are better for the job they were made for and wrong for the one they were not.

None of them is a reason to throw away the originals. grep, find, sed, cat and curl are on every machine you will ever log into, and a script that uses them runs everywhere. Use the new tools for your own hands, and keep the old ones for your scripts.