17 GNU Coreutils Flags You've Never Used But Should (2026 Edition)
Quick answer: GNU coreutils ships with hundreds of flags that solve specific real-world problems and that almost nobody uses because they never came up in a tutorial. This reference lists 17 of them — each with the exact command, the problem it solves, and a copy-paste example. All flags work with GNU coreutils 9.5 or later (shipped in Debian 13, Ubuntu 26.04, Fedora 42, RHEL 10, Arch). Most also work on macOS via brew install coreutils (commands prefixed with g: gls, gcp, etc.).
Last updated: 2026-05-23 — verified against GNU coreutils 9.5 (released 2024-03-28) and 9.6-pre.
Why this list exists
Most coreutils tutorials cover the same 8 flags (ls -la, cp -r, grep -i, etc.). GNU coreutils contains roughly 640 documented flags across 95 commands. The 17 below are chosen by a single criterion: each one solves a problem that comes up regularly in real sysadmin and development work but that most users solve with a longer pipeline or an external tool. Each entry is self-contained — you can copy the example, paste it into a terminal, and see the behavior immediately.
1. cp --reflink=auto — instant copies on supported filesystems
Problem: Copying a 50 GB file takes minutes and doubles disk usage.
Solution: On btrfs, XFS (with reflink=1), and bcachefs, cp --reflink=auto creates a copy-on-write clone in milliseconds, using zero additional disk space until one copy is modified.
cp --reflink=auto huge-dataset.tar.zst huge-dataset.backup.tar.zst
# Completes in <50 ms regardless of file size
Verify your filesystem supports it: mount | grep -E 'btrfs|xfs|bcachefs'. On ext4, the flag silently falls back to a full copy.
2. mv -n — refuse to overwrite, without prompting
Problem: mv overwrites destination files silently. mv -i prompts interactively, which breaks scripts.
Solution: mv -n (no-clobber) skips any move where the destination exists, with no prompt and no error.
mv -n *.log /var/log/archive/
# Existing files in archive are preserved; new ones move
3. ls --hyperlink=auto — clickable file paths in modern terminals
Problem: ls output is text; you have to copy a filename to open it elsewhere.
Solution: Terminals that support OSC 8 hyperlinks (kitty, WezTerm, foot, Ghostty, recent iTerm2 and Konsole) render ls --hyperlink=auto output as clickable links.
alias ls='ls --hyperlink=auto --color=auto'
ls ~/Documents
# Cmd-click or Ctrl-click opens the file
4. sort -h — human-numeric sort for sizes
Problem: Sorting 1K, 2M, 500K, 1G lexicographically gives nonsense.
Solution: sort -h understands SI suffixes (K, M, G, T) and sorts numerically.
du -h --max-depth=1 /var/log | sort -h
# Output sorted smallest-to-largest by actual size
5. du --max-depth=N — limit recursion for fast directory audits
Problem: du -h / runs for an hour and produces millions of lines.
Solution: du --max-depth=1 (or -d 1 on macOS coreutils) returns only the top-level totals, fast.
du -h --max-depth=1 / 2>/dev/null | sort -h
# One line per top-level directory, sorted by size
6. tail -F (capital F) — follow with retry on rotation
Problem: tail -f /var/log/app.log stops working when logrotate renames the file.
Solution: tail -F reopens the file by name if it disappears or shrinks. Survives log rotation without intervention.
tail -F /var/log/nginx/access.log
# Continues following across rotation
7. dd status=progress — see throughput in real time
Problem: dd is silent until it finishes, leaving you guessing whether a 32 GB image flash is hung or progressing.
Solution: status=progress prints byte count and throughput once per second.
dd if=debian-13.iso of=/dev/sdX bs=4M status=progress oflag=sync
# Live progress: 4194304000 bytes (4.2 GB) copied, 38 s, 110 MB/s
8. cat -A — reveal whitespace and line endings
Problem: A file looks identical to another but behaves differently. Hidden CRLF line endings, tabs, or trailing spaces are the cause.
Solution: cat -A shows tabs as ^I, line endings as $, and CRLF as ^M$.
cat -A suspicious-config.yaml
# server:^I^Iexample.com^M$
# ^^^ CRLF — that's the bug
9. wc -L — find the longest line in a file
Problem: A linter complains about line length but won't tell you which line.
Solution: wc -L returns the length of the longest line. Combined with awk, finds the line itself.
wc -L src/index.ts # 412
awk 'length > 120 {print NR": "length" chars"}' src/index.ts
# 47: 412 chars
10. shuf -n N — random sample from a file or pipeline
Problem: You need 10 random lines from a 10-million-line log for spot checks.
Solution: shuf -n 10 returns a random sample without loading the entire file shuffled.
shuf -n 10 /var/log/nginx/access.log
# 10 random log lines, uniform sample
11. stat -c '%Y' file — file mtime as Unix timestamp
Problem: You want the modification time of a file for arithmetic, not for display.
Solution: stat -c '%Y' outputs the mtime as a Unix epoch integer, ideal for shell math.
age_seconds=$(( $(date +%s) - $(stat -c '%Y' /etc/letsencrypt/live/example.com/cert.pem) ))
echo "Cert is $((age_seconds / 86400)) days old"
12. tr -d '
' — strip carriage returns from Windows files
Problem: A shell script written on Windows fails with bad interpreter: No such file or directory because of CRLF.
Solution: tr -d '
' strips carriage returns. Faster than dos2unix and always available.
tr -d '
' < windows-script.sh > unix-script.sh && chmod +x unix-script.sh
13. sort -V — version-aware sort
Problem: Sorting 1.2.10 and 1.2.9 lexicographically puts 1.2.10 first.
Solution: sort -V treats version numbers correctly.
ls /opt/myapp/releases/ | sort -V
# v1.2.9
# v1.2.10
# v1.3.0
14. cp --parents — preserve directory structure when copying selected files
Problem: You want to copy src/a/b/c.txt and src/x/y/z.txt into a backup, keeping their relative paths.
Solution: cp --parents recreates the source directory tree under the destination.
cp --parents src/a/b/c.txt src/x/y/z.txt backup/
# Creates backup/src/a/b/c.txt and backup/src/x/y/z.txt
15. numfmt --to=iec — convert bytes to human-readable, scriptably
Problem: A pipeline outputs 4831838208 and you want 4.5G without writing your own formatter.
Solution: numfmt --to=iec (or --to=si) handles the conversion both directions.
echo 4831838208 | numfmt --to=iec # 4.5G
echo "1.5G" | numfmt --from=iec # 1610612736
16. timeout --kill-after=Ns Ts cmd — escalate from SIGTERM to SIGKILL
Problem: timeout 30 some-command sends SIGTERM, but the process ignores it.
Solution: --kill-after schedules a SIGKILL if the process is still alive N seconds after the SIGTERM.
timeout --kill-after=5s 30s slow-flaky-script.sh
# SIGTERM at 30 s, SIGKILL at 35 s if still running
17. cp -a vs cp -r — when you actually want a faithful copy
Problem: cp -r loses symlinks (follows them), strips permissions in subtle ways, and resets timestamps.
Solution: cp -a (archive mode) is equivalent to cp -dR --preserve=all — preserves symlinks as symlinks, permissions, ownership (when root), timestamps, and extended attributes.
cp -a /etc /backup/etc-$(date +%F)
# Faithful copy, suitable for snapshot use
How to discover more flags like these
Every coreutils command has two documentation surfaces: the man page (concise, options-focused) and the info page (long-form, with examples). The info page is consistently more useful and consistently underread:
info coreutils ls invocation
info coreutils 'cp invocation'
Run info coreutils with no arguments for the full table of contents — 95 commands, each with its own section.
Frequently asked questions
Do these flags work on macOS?
The macOS base system ships BSD coreutils, which has a different (and smaller) flag set. To get GNU coreutils on macOS: brew install coreutils. Commands are then prefixed with g: gls, gcp, gdu, etc. Add $(brew --prefix)/opt/coreutils/libexec/gnubin to your PATH to use unprefixed names.
Do these flags work on BusyBox (Alpine, embedded systems)?
Partially. BusyBox implements a subset of GNU flags by default. --reflink, --parents, --hyperlink, -V sort, and numfmt are not in standard BusyBox. To get full GNU semantics on Alpine: apk add coreutils.
What is the difference between GNU coreutils and POSIX coreutils?
POSIX specifies a minimal common subset of utilities and their flags. GNU coreutils extends POSIX with hundreds of additional flags (--long-option form, GNU-specific behaviors). Every flag in this article except dd status=progress is a GNU extension; portable scripts targeting BSD or Solaris must avoid them.
How do I check my coreutils version?
ls --version (or any coreutils command with --version) prints the version on the first line. GNU coreutils 9.5 is current as of mid-2026.
Is there a complete reference for all coreutils flags?
Yes: info coreutils covers every command and every documented flag. The HTML version is at gnu.org/software/coreutils/manual/coreutils.html. The man pages are shorter and less complete.
Which of these flags are dangerous in scripts?
cp --reflink=auto is safe (falls back). tail -F is safe. mv -n is safe (no destructive overwrite). The only entry in this list with a sharp edge is cp -a against a destination that already contains files — it will overwrite without prompting. Combine with mv -n or test the destination first if that matters.
Sources and further reading
- GNU coreutils manual (gnu.org)
- GNU coreutils release announcements
- Reflink support matrix (kernel.org)
- POSIX.1-2024 utilities specification (Open Group)
- Related on GNU Today: The Complete Map of Linux Init Systems in 2026 · GNU Hurd in 2026: How Close Is 'Almost There', Really?
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "17 GNU Coreutils Flags You've Never Used But Should (2026 Edition)",
"datePublished": "2026-05-23",
"dateModified": "2026-05-23",
"author": {
"@type": "Organization",
"name": "GNU Today",
"url": "https://gnutoday.com"
},
"publisher": {
"@type": "Organization",
"name": "GNU Today",
"url": "https://gnutoday.com"
},
"description": "A practical reference of 17 underused GNU coreutils flags — ls, cp, mv, sort, du, tail, dd, and more — with copy-paste examples.",
"mainEntityOfPage": "https://gnutoday.com/gnu-coreutils-flags-you-should-know"
}