opscape

Text processing

cmp

Compare two files byte by byte and report the first difference, or just whether they differ.

cmp [OPTION...] FILE1 [FILE2 [SKIP1 [SKIP2]]]

9 of 9 examples run in Debian 13.7 on 2026-10-31 · diffutils 1:3.10-4 · manual: cmp(1)

cmp compares two files as raw bytes and stops at the first byte that differs. It does not care about lines or text, which makes it the right tool for binaries (images, archives, compiled programs) and the fastest way to answer "are these two files identical?".

Its output is one line naming the byte and line number of the first difference. With -s it prints nothing and you use the exit status: 0 identical, 1 different, 2 trouble. If you need to see what changed in a text file, use diff; to compare files you cannot put side by side (on different machines), compare their sha256sum hashes instead.

Examples

Find the first difference between two files

sed 's/fix logout/fix signup/' todo.txt > todo2.txt
cmp todo.txt todo2.txt
outputexit 1
todo.txt todo2.txt differ: byte 40, line 4

cmp stops at the first differing byte and reports its position counted from 1, along with the line it is on. The exit status is 1.

Identical files print nothing

cp photos/beach.png copy.png
cmp photos/beach.png copy.png && echo "identical"
output
identical

When the files match, cmp is silent and exits with 0. It works the same on images or any other binary file.

Test for equality in a script with -s

if cmp -s photos/beach.png photos/forest.png; then echo same; else echo "different (status $?)"; fi
explain
output
different (status 1)

-s suppresses all output, so only the exit status speaks. Inside the else branch $? still holds cmp's status, 1.

Compare binary files

cmp photos/beach.png photos/forest.png
explain
outputexit 1
photos/beach.png photos/forest.png differ: byte 19, line 3

Both are PNG images, so the first bytes (the PNG signature and header) are the same. The first difference is inside the header, where the image dimensions are stored. The "line" number counts newline bytes, which means little in binary data.

List every differing byte with -l

printf 'hello world\n' > a.txt
printf 'hallo world!\n' > b.txt
cmp -l a.txt b.txt
outputexit 1
cmp: EOF on a.txt after byte 12
 2 145 141
12  12  41

-l prints every difference as the byte position and the two values in octal: 145 is e, 141 is a. Position 12 is where b.txt has ! (41) and a.txt its newline (12). After that a.txt ends while b.txt has one more byte, which cmp reports as EOF on stderr; that note shows up first only because stderr is not buffered.

Show the differing characters with -b

sed 's/fix logout/fix signup/' todo.txt > todo2.txt
cmp -b todo.txt todo2.txt
outputexit 1
todo.txt todo2.txt differ: byte 40, line 4 is 154 l 163 s

-b adds the two differing bytes, both in octal and as characters, so you can see the l of logout against the s of signup.

Detect when one file is a prefix of the other

head -3 todo.txt > short.txt
cmp todo.txt short.txt
outputexit 1
cmp: EOF on short.txt after byte 35, line 3

When the files agree until one runs out, cmp reports EOF on the shorter one. That is still a difference, so the status is 1.

Compare only the first bytes with -n

cmp -n 8 photos/beach.png photos/forest.png && echo "same 8-byte signature"
explain
output
same 8-byte signature

-n 8 stops after eight bytes. Every PNG file starts with the same eight-byte signature, so both images match within that range.

A missing file is status 2

cmp todo.txt nosuch.txt
explain
outputexit 2
cmp: nosuch.txt: No such file or directory

Status 2 means cmp could not compare, which a script should treat differently from "the files differ".

Common pitfalls

  • cmp stops at the first difference. To count or list all of them, use -l (bytes) or diff (lines).

  • Treating any non-zero status as "different" hides errors like a missing file. Check for 1 and 2 separately.

  • Line endings count: a file saved with CRLF and its LF copy differ at the first line ending even though they look the same.

GNU vs BSD and macOS

The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).

  • -s, -l and the exit statuses are POSIX and behave the same everywhere. -b, -n and -i are extensions; the BSD and macOS cmp have their own set, so check the local man page before using them in portable scripts.

Options worth knowing

A selection, described in our own words. For the full list, see cmp(1) or cmp --help.

OptionWhat it does
-s, --quietPrint nothing; report only through the exit status.
-l, --verboseList the position and octal values of every differing byte.
-b, --print-bytesAlso print the differing bytes.
-n, --bytes LIMITCompare at most LIMIT bytes.
-i, --ignore-initial SKIPSkip the first SKIP bytes of both files (or SKIP1:SKIP2).

Related