Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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

LayerWhat it fixesExamples in this collection
POSIX 2018Syntax, options, exit codes for ~100 utilitiesls, cp, sort, tr, test
GNU extensionsEverything POSIX leaves open: long options, -h sizes, deeper formatssort -h -V, du --apparent-size, date -d
GNU-only toolsUtilities POSIX does not definenumfmt, 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)

BinaryOne-linerPage
cpCopy files and directoriescp
ddBlock-level copy and convertdd
installCopy with mode/owner/timestamp controlinstall
lnCreate hard and symbolic linksln
lsList directory contentsls
dirls equivalent with different defaultsdir
vdirls -l equivalentvdir
dircolorsGenerate LS_COLORS setupdircolors
mkdirCreate directoriesmkdir
mkfifoCreate named pipesmkfifo
mknodCreate device and FIFO nodesmknod
mktempCreate secure temporary files/dirsmktemp
mvMove/rename filesmv
realpathResolve canonical pathsrealpath
rmRemove files and treesrm
rmdirRemove empty directoriesrmdir
shredOverwrite in place before deleteshred
syncFlush page cache to disksync
touchCreate/retimestamp filestouch
truncateResize to a lengthtruncate
statFile/inode status detailstat
dfFilesystem capacitydf
duDirectory disk usagedu
chconChange SELinux file contextchcon

Ownership and metadata

BinaryOne-linerPage
chgrpChange group ownershipchgrp
chmodChange permission bitschmod
chownChange user/group ownershipchown

Text processing (39)

BinaryOne-linerPage
base32RFC 4648 base-32 codecbase32
base64RFC 4648 base-64 codecbase64
basencUnified encoder (base16/32/64url/z85)basenc
catConcatenate and printcat
cksumCRC32 and newer checksumscksum
commCompare two sorted files line-wisecomm
csplitSplit by context/regexcsplit
cutSlice fields/bytes/columnscut
expandTabs to spacesexpand
fmtReflow paragraphsfmt
foldWrap fixed widthfold
headFirst lines/byteshead
tailLast lines/bytes, follow modetail
joinRelational join on a fieldjoin
nlNumber lines with stylesnl
numfmtHuman-readable number conversionnumfmt
odOctal/byte-level dumpod
pasteMerge lines column-wisepaste
prPaginate for printingpr
ptxPermuted indexptx
shufRandom permutationshuf
sortSort lines (keys, numeric, version)sort
splitSplit into chunkssplit
tacReverse linestac
teeTap a pipelinetee
trTranslate/delete characterstr
tsortTopological sorttsort
unexpandSpaces to tabsunexpand
uniqCollapse/report repeated linesuniq
wcCount lines/words/byteswc

Checksums (9)

BinaryOne-linerPage
md5sumMD5 checksums (format anchor)md5sum
sha1sumSHA-1 checksumssha1sum
sha224sumSHA-224 checksumssha224sum
sha256sumSHA-256 checksumssha256sum
sha384sumSHA-384 checksumssha384sum
sha512sumSHA-512 checksumssha512sum
b2sumBLAKE2 checksumsb2sum
sumLegacy BSD/SysV checksumssum
printenvPrint environment variablesprintenv

Shell and system (32)

BinaryOne-linerPage
archPrint machine architecturearch
basenameStrip directory/suffixbasename
chrootRun in a new rootchroot
datePrint/convert datesdate
dirnameStrip last componentdirname
echoPrint argumentsecho
envRun with modified environmentenv
exprEvaluate expressions (legacy)expr
factorPrime factorizationfactor
falseExit 1false
groupsPrint group membershipsgroups
hostidPrint numeric host idhostid
idPrint uid/gid identityid
linklink(2) wrapperlink
lognameLogin name from utmplogname
niceRun at adjusted nicenessnice
nohupImmune to SIGHUPnohup
nprocCPU countnproc
pathchkCheck path portabilitypathchk
pinkyLightweight fingerpinky
printfFormat and print dataprintf
pwdPrint working directorypwd
readlinkResolve symlink targetsreadlink
runconRun in a security contextruncon
seqPrint number sequencesseq
sleepDelay for an intervalsleep
stdbufAdjust stdio bufferingstdbuf
sttyTerminal line disciplinestty
testFile/condition checks ([)test
timeoutRun with a time limittimeout
trueExit 0true
ttyPrint terminal nametty
unameKernel/system infouname
unlinkunlink(2) wrapperunlink
usersCurrent login namesusers
whoWho is logged inwho
whoamiEffective usernamewhoami
yesRepeat a string foreveryes

Shared Conventions Worth Knowing Once

Every page assumes these; knowing them once saves repetition.

  • Long options: GNU coreutils accepts --long-name and unique prefixes; -- ends option parsing, which is why touch -- "$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 -; dd and cat also accept /dev/stdin, which matters for process substitution.
  • Locale: collation and character classes change behavior under non-C locales — the sort and tr pages show concrete traps and the LC_ALL=C fix.
  • Signal discipline: text filters die on SIGPIPE (exit 143) unless they opt out; tail -f, tee -p, and timeout --preserve-status each handle this differently — covered on their pages.

Reading Order For Interview Prep

  1. Flagships first: ls, cp, mv, rm, chmod, chown, sort, df, du, stat.
  2. Pipeline tools: cut, tr, head, tail, tee, uniq, wc, od.
  3. Scripting load-bearers: test, printf, env, mktemp, timeout, date.
  4. 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.

References