2026-04-30
In 2006, Joey Hess looked at the standard Unix toolkit and noticed the gaps — tiny operations you need constantly but end up hacking around with temp files and subshells. He wrote moreutils, a collection of roughly 15 small tools that should have been in coreutils from the start. Most developers have never installed it. That's a mistake.
Install it and get instantly productive:
# Debian/Ubuntu
sudo apt install moreutils
# macOS
brew install moreutils
# Fedora
sudo dnf install moreutils
sponge — the tool that fixes the oldest shell footgun. You've hit this:
# THIS DESTROYS data.txt — the redirect truncates before sort reads
sort data.txt > data.txt
# The old workaround: temp files like an animal
sort data.txt > /tmp/sorted && mv /tmp/sorted data.txt
# With sponge: soaks up all input, THEN writes
sort data.txt | sponge data.txt
sponge buffers the entire stdin before opening the output file. It works everywhere you want to read and write the same file in a pipeline. Strip comments from a config, deduplicate a hosts file, reformat JSON — all in place:
jq '.users | sort_by(.name)' db.json | sponge db.json
grep -v '^#' config.ini | sponge config.ini
ts — prepend timestamps to every line of output. Indispensable for long-running processes where you need to know when something happened, not just what:
# Default: absolute timestamps
tail -f /var/log/syslog | ts
# Apr 30 14:23:01 some log line
# Apr 30 14:23:04 another log line
# Elapsed time since ts started
long_build_command 2>&1 | ts -s
# 00:00:00 Compiling module 1...
# 00:02:17 Compiling module 2...
# 00:15:43 Linking...
# Incremental (time since last line) — find the slow step
make 2>&1 | ts -i
# 00:00:00 Building libfoo
# 00:00:03 Building libbar
# 00:04:22 Building libbaz ← there's your bottleneck
# Custom strftime format
command | ts '%H:%M:%.S'
chronic — runs a command silently unless it fails. Built for cron jobs where you only want mail on errors:
# Crontab without chronic: spews output on every success
0 * * * * /usr/local/bin/backup.sh
# With chronic: silent on success, full output on failure
0 * * * * chronic /usr/local/bin/backup.sh
# chronic -e also triggers on stderr output (even with exit 0)
chronic -e /usr/local/bin/flaky-script.sh
vidir — edit a directory listing in your $EDITOR. Rename files using vim motions, delete lines to delete files:
# Open current dir in vim — edit filenames, save, done
vidir
# Bulk rename photos
ls *.jpg | vidir -
# Combined with find for surgical renames
find . -name '*.bak' | vidir -
ifdata — query network interfaces without parsing ifconfig or ip output:
ifdata -pa eth0 # print address: 192.168.10.5
ifdata -pn eth0 # print netmask: 255.255.255.0
ifdata -si eth0 # incoming bytes
ifdata -so eth0 # outgoing bytes
Other gems worth knowing: errno looks up errno names and descriptions (errno ENOENT), combine performs set operations on files (union, intersection, difference), and parallel runs jobs in parallel with a simpler interface than GNU parallel (though with fewer features).
The entire collection weighs almost nothing — no dependencies, no daemons, no config files. Each tool does exactly one thing. They compose with pipes like everything else. That's the point.
moreutils fills the cracks in your Unix toolkit — sponge for safe in-place pipelines, ts for timestamping output, chronic for quieting cron — small tools that eliminate entire categories of shell hacks.
