GNU Coreutils — Collection Overview
The GNU Core Utilities — always “coreutils” — is the package that makes a Linux system feel like Linux. Its 104 binaries cover file operations, text processing, checksums, and the small shell-facing tools that scripts lean on every minute. This collection gives each binary its own page: synopsis in man-page style, mechanics, the options that matter, gotchas, and interview questions. An Overview facts table on every page anchors the basics; this page carries what the binaries share.
Why One Page Per Binary
Two binaries that look similar are usually separated by a real behavioral
boundary — cp and mv differ in inode bookkeeping, not just a rename
syscall; head -n -5 and tail -n +5 look symmetric but parse differently.
Interview questions exploit exactly those boundaries, so this collection
keeps each tool’s semantics on its own page and uses cross-links for shared
concepts. The checksum family is the clearest example: md5sum explains the
coreutils checksum-file format once, and sha256sum links to it instead of
restating it.
Lineage
Coreutils descends from the Unix userland of the 1970s, was assembled as the
GNU “fileutils”, “textutils”, and “sh-utils” packages through the 1980s and
1990s, and merged into one package in 2002. It has shipped as the default
userland on every major GNU/Linux distribution since. Debian’s coreutils
package (bookworm ships the 9.1 series; current upstream is the 9.x line)
installs everything under /usr/bin — the historical /bin split collapsed
with the usrmerge. Today the package is unusually stable: interfaces added
decades ago are still supported, and new options arrive slowly and
conservatively, which is exactly why mastery pays off across every distro
you will ever touch.
The Rust rewrite project uutils is re-implementing this package command by command and is already being adopted by Ubuntu — see uutils Coreutils Overview for the compatibility picture. Its per-command status page is the fastest way to check whether a portability concern applies to you.
Standards Position
| Layer | What it fixes | Examples in this collection |
|---|---|---|
| POSIX 2018 | Syntax, options, exit codes for ~100 utilities | ls, cp, sort, tr, test |
| GNU extensions | Everything POSIX leaves open: long options, -h sizes, deeper formats | sort -h -V, du --apparent-size, date -d |
| GNU-only tools | Utilities POSIX does not define | numfmt, shuf, stdbuf, timeout, runcon |
The rule of thumb: when a page’s Nuances section mentions portability, the GNU behavior described is what you get on Debian/Ubuntu/RHEL/Fedora; the BSDs and BusyBox often implement the POSIX subset plus their own divergences. When a script must survive those platforms, prefer the POSIX core and test.
The Inventory
File operations (24)
| Binary | One-liner | Page |
|---|---|---|
cp | Copy files and directories | cp |
dd | Block-level copy and convert | dd |
install | Copy with mode/owner/timestamp control | install |
ln | Create hard and symbolic links | ln |
ls | List directory contents | ls |
dir | ls equivalent with different defaults | dir |
vdir | ls -l equivalent | vdir |
dircolors | Generate LS_COLORS setup | dircolors |
mkdir | Create directories | mkdir |
mkfifo | Create named pipes | mkfifo |
mknod | Create device and FIFO nodes | mknod |
mktemp | Create secure temporary files/dirs | mktemp |
mv | Move/rename files | mv |
realpath | Resolve canonical paths | realpath |
rm | Remove files and trees | rm |
rmdir | Remove empty directories | rmdir |
shred | Overwrite in place before delete | shred |
sync | Flush page cache to disk | sync |
touch | Create/retimestamp files | touch |
truncate | Resize to a length | truncate |
stat | File/inode status detail | stat |
df | Filesystem capacity | df |
du | Directory disk usage | du |
chcon | Change SELinux file context | chcon |
Ownership and metadata
| Binary | One-liner | Page |
|---|---|---|
chgrp | Change group ownership | chgrp |
chmod | Change permission bits | chmod |
chown | Change user/group ownership | chown |
Text processing (39)
| Binary | One-liner | Page |
|---|---|---|
base32 | RFC 4648 base-32 codec | base32 |
base64 | RFC 4648 base-64 codec | base64 |
basenc | Unified encoder (base16/32/64url/z85) | basenc |
cat | Concatenate and print | cat |
cksum | CRC32 and newer checksums | cksum |
comm | Compare two sorted files line-wise | comm |
csplit | Split by context/regex | csplit |
cut | Slice fields/bytes/columns | cut |
expand | Tabs to spaces | expand |
fmt | Reflow paragraphs | fmt |
fold | Wrap fixed width | fold |
head | First lines/bytes | head |
tail | Last lines/bytes, follow mode | tail |
join | Relational join on a field | join |
nl | Number lines with styles | nl |
numfmt | Human-readable number conversion | numfmt |
od | Octal/byte-level dump | od |
paste | Merge lines column-wise | paste |
pr | Paginate for printing | pr |
ptx | Permuted index | ptx |
shuf | Random permutation | shuf |
sort | Sort lines (keys, numeric, version) | sort |
split | Split into chunks | split |
tac | Reverse lines | tac |
tee | Tap a pipeline | tee |
tr | Translate/delete characters | tr |
tsort | Topological sort | tsort |
unexpand | Spaces to tabs | unexpand |
uniq | Collapse/report repeated lines | uniq |
wc | Count lines/words/bytes | wc |
Checksums (9)
| Binary | One-liner | Page |
|---|---|---|
md5sum | MD5 checksums (format anchor) | md5sum |
sha1sum | SHA-1 checksums | sha1sum |
sha224sum | SHA-224 checksums | sha224sum |
sha256sum | SHA-256 checksums | sha256sum |
sha384sum | SHA-384 checksums | sha384sum |
sha512sum | SHA-512 checksums | sha512sum |
b2sum | BLAKE2 checksums | b2sum |
sum | Legacy BSD/SysV checksums | sum |
printenv | Print environment variables | printenv |
Shell and system (32)
| Binary | One-liner | Page |
|---|---|---|
arch | Print machine architecture | arch |
basename | Strip directory/suffix | basename |
chroot | Run in a new root | chroot |
date | Print/convert dates | date |
dirname | Strip last component | dirname |
echo | Print arguments | echo |
env | Run with modified environment | env |
expr | Evaluate expressions (legacy) | expr |
factor | Prime factorization | factor |
false | Exit 1 | false |
groups | Print group memberships | groups |
hostid | Print numeric host id | hostid |
id | Print uid/gid identity | id |
link | link(2) wrapper | link |
logname | Login name from utmp | logname |
nice | Run at adjusted niceness | nice |
nohup | Immune to SIGHUP | nohup |
nproc | CPU count | nproc |
pathchk | Check path portability | pathchk |
pinky | Lightweight finger | pinky |
printf | Format and print data | printf |
pwd | Print working directory | pwd |
readlink | Resolve symlink targets | readlink |
runcon | Run in a security context | runcon |
seq | Print number sequences | seq |
sleep | Delay for an interval | sleep |
stdbuf | Adjust stdio buffering | stdbuf |
stty | Terminal line discipline | stty |
test | File/condition checks ([) | test |
timeout | Run with a time limit | timeout |
true | Exit 0 | true |
tty | Print terminal name | tty |
uname | Kernel/system info | uname |
unlink | unlink(2) wrapper | unlink |
users | Current login names | users |
who | Who is logged in | who |
whoami | Effective username | whoami |
yes | Repeat a string forever | yes |
Shared Conventions Worth Knowing Once
Every page assumes these; knowing them once saves repetition.
- Long options: GNU coreutils accepts
--long-nameand unique prefixes;--ends option parsing, which is whytouch -- "$file"is the safe pattern for hostile filenames. - Exit codes: 0 success, 1 minor failure (per-file errors keep going),
2 serious trouble (bad invocation, missing operand). Tools that verify
(
test,cmp,sort -c) use 1 to mean “check failed”, not “crashed”. --help/--version: consistent across the package and the basis of most of this book’s flag tables.-and/dev/stdin: most text tools read stdin on-;ddandcatalso accept/dev/stdin, which matters for process substitution.- Locale: collation and character classes change behavior under
non-
Clocales — thesortandtrpages show concrete traps and theLC_ALL=Cfix. - Signal discipline: text filters die on SIGPIPE (exit 143) unless they
opt out;
tail -f,tee -p, andtimeout --preserve-statuseach handle this differently — covered on their pages.
Reading Order For Interview Prep
- Flagships first: ls, cp, mv, rm, chmod, chown, sort, df, du, stat.
- Pipeline tools: cut, tr, head, tail, tee, uniq, wc, od.
- Scripting load-bearers: test, printf, env, mktemp, timeout, date.
- The rest is breadth — skim One-liners above and target gaps.
Text-search siblings that are NOT coreutils live in the shell collection: find, grep, sed and awk, and xargs have their own deep pages there.
Interview Questions
Q: Why does sort -u not replace sort | uniq?
They agree on output but differ in semantics and cost. sort -u dedupes on
the full line only by default, while uniq -c and friends operate on
adjacent duplicates with field-skipping options (-f, -s, -w) that
sort -u cannot express; and sort | uniq -c | sort -rn builds histograms
you cannot get from -u. With GNU sort’s parallel and external-merge
machinery a single sort -u is usually faster for plain dedup, which is
precisely the trade-off interviewers want you to articulate.
Q: What do exit codes 0, 1, and 2 mean across coreutils?
0 is success; 1 is a minor failure where per-file work continued (a file
disappeared mid-du, a checksum mismatch with md5sum -c); 2 is serious
trouble such as a bad invocation or missing operand. Verification tools
reuse 1 to mean “the check itself failed” — test/[ returns 1 for a
false condition — so shell code must treat 1 as data, not as an error.
Q: Why do scripts write touch -- "$file" and rm -- "$file"?
A filename like -f would otherwise parse as an option. -- ends option
parsing for every coreutils tool, making the argument list unambiguous. The
same pattern protects cp, mv, and sort pipelines fed by hostile or
machine-generated names.
Q: Where does the userland end and the shell begin?
Coreutils binaries are external programs; the shell builtin set (cd,
export, [[, $(( ))) is not part of coreutils. That is why
/usr/bin/echo and the bash builtin echo differ in details like -e, and
why printf is the portable choice — the same tension is covered on the
echo and printf pages.