Linux Tutorial / Compare Files with diff and cmp

Use diff when you need to see which text lines changed and how, and cmp when you need to know whether two files are identical byte for byte. Both generally return exit status 1 when the files differ, distinct from status 2 for trouble running the comparison. This lesson makes two small files and examines both output and exit status.

Prepare two files to compare

The exercise assumes Bash and GNU Diffutils. If ~/linux-course-13-practice exists, choose another directory name. Stop if the initial mkdir fails; the later > commands can overwrite existing files.

mkdir ~/linux-course-13-practice
cd ~/linux-course-13-practice
pwd

Once you have confirmed the location, create the files. Only the second line differs: beta versus BETA.

printf 'alpha\nbeta\ngamma\n' > old.txt
printf 'alpha\nBETA\ngamma\n' > new.txt

Read changed lines with diff

diff compares lines. -u selects unified format, which includes nearby unchanged lines. GNU --label replaces the usual filename-and-time headers with stable labels for this example.

diff -u --label old --label new old.txt new.txt

The practice files produce:

--- old
+++ new
@@ -1,3 +1,3 @@
 alpha
-beta
+BETA
 gamma

--- marks the earlier input and +++ the later input. The @@ header identifies the line range. A line beginning with - comes from the first file, one beginning with + from the second, and one beginning with a space is unchanged. diff does not know which file you consider the real original: argument order sets the comparison direction.

Find the first byte difference with cmp

cmp compares bytes and normally reports the location of the first difference. Here that is the first letter of the second line, after alpha and its newline.

cmp old.txt new.txt

With GNU cmp in an English locale, the message can look like old.txt new.txt differ: byte 7, line 2. Wording may change with filenames and locale, but the point is that the first difference is on line two. cmp does not list every later difference.

For a silent equality check, add -s and immediately examine the exit status. Since these files differ, this prints 1. $? refers to the most recently completed command; placing another command between the two lines would change what it reports.

cmp -s old.txt new.txt
echo $?

Distinguish differences from errors

Exit status Usual meaning for diff and cmp What to check
0 No difference found Confirm you compared the intended inputs
1 Files differ Read diff output for changed text
2 Trouble, such as an unreadable file Path, permission, and error message

cmp is a good fit for byte equality; diff -u is better for understanding a text change. Different line endings or encodings can create differences even when text looks similar. For a binary file, a text diff may not be helpful, so start with cmp if exact identity is the question. GNU diff -r can compare directory trees, but first check the paths because that expands the scope of comparison.

Official documentation

The GNU Diffutils manual documents unified output, cmp, and the exit statuses of both commands.

More in This Category
Linux Administration Memo: Essential Commands and System Checks

Linux Administration Memo: Essential Commands and System Checks

A compact Linux administration reference for checking system information, processes, storage, networking, users, permissions, services, and logs.

Linux clear Command: Clear the Terminal Display

Linux clear Command: Clear the Terminal Display

Learn how to use the Linux clear command to clear the visible terminal screen and understand scrollback behavior, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux sed Command: Search and Replace Text Streams

Linux sed Command: Search and Replace Text Streams

Learn how to search and Replace Text Streams with the Linux sed command, including practical examples, key options, and important precautions.

Linux bunzip2 Command: Decompress bzip2 Files

Linux bunzip2 Command: Decompress bzip2 Files

Learn how to decompress bzip2 Files with the Linux bunzip2 command, including practical examples, key options, and important precautions.

Linux wc Command: Count Lines, Words, Characters, and Bytes

Linux wc Command: Count Lines, Words, Characters, and Bytes

Learn how to use the Linux wc command to count lines, words, characters, and bytes in files or standard input, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux pgrep Command: Find Process IDs by Name or Criteria

Linux pgrep Command: Find Process IDs by Name or Criteria

Learn how to find Process IDs by Name or Criteria with the Linux pgrep command, including practical examples, key options, and important precautions.

Linux blkid Command: Find Block-Device UUIDs and Filesystem Types

Linux blkid Command: Find Block-Device UUIDs and Filesystem Types

Learn how to find Block-Device UUIDs and Filesystem Types with the Linux blkid command, including practical examples, key options, and important precautions.

Linux realpath Command: Resolve Absolute and Canonical Paths

Linux realpath Command: Resolve Absolute and Canonical Paths

Learn how to use the Linux realpath command to resolve relative paths, symbolic links, and redundant path components, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux dirname Command: Extract the Directory Part of a Path

Linux dirname Command: Extract the Directory Part of a Path

Learn how to use the Linux dirname command to remove the final component of a path and return its directory portion, with essential options, practical examples, output interpretation, and common troubleshooting tips.

Linux apt Command: Manage Packages on Debian and Ubuntu

Linux apt Command: Manage Packages on Debian and Ubuntu

Learn how to manage Packages on Debian and Ubuntu with the Linux apt command, including practical examples, key options, and important precautions.