GNU cmp normally prints nothing when two files have identical contents. With -s, it prints nothing even when they differ or a comparison fails. Silence is therefore not enough evidence: inspect the exit status and distinguish matching bytes, different bytes and comparison trouble.
This is useful when checking a copied configuration or small export without displaying its contents. It is a byte comparison, not a decision that the configuration is valid or safe to deploy.
Understand the three outcomes
The GNU Diffutils manual defines status 0 as no differences found, 1 as differences found, and 2 as trouble. A missing input is trouble, not a content difference. In automation, treating every nonzero status as “changed” can send an unreadable or nonexistent file into a deployment workflow.
Without quiet mode, cmp generally reports the first differing byte and line, or reports that one file ended before the other. Those positions start at one. With -s, messages are suppressed; your script must provide its own useful interpretation. Preserve the real filenames and investigate access errors through an appropriate diagnostic step rather than declaring a successful comparison.
Try equal, different and missing inputs safely
Run the following complete example in Bash. It creates only a temporary practice directory, compares disposable files and removes that directory when the subshell exits. It does not read or overwrite your production configuration.
(
work=$(mktemp -d) || exit 1
trap 'rm -rf -- "$work"' EXIT
printf 'mode=demo\n' > "$work/original"
printf 'mode=demo\n' > "$work/same"
printf 'mode=other\n' > "$work/different"
compare_pair() {
local status
if cmp -s -- "$1" "$2"; then
status=0
else
status=$?
fi
case "$status" in
0) printf 'MATCH\n' ;;
1) printf 'DIFFERENT\n' ;;
*) printf 'ERROR status=%s\n' "$status" ;;
esac
return "$status"
}
compare_pair "$work/original" "$work/same" || :
compare_pair "$work/original" "$work/different" || :
compare_pair "$work/original" "$work/missing" || :
)
With GNU cmp, expect the three result lines to be MATCH, DIFFERENT and ERROR status=2. The || : suffix deliberately lets this demonstration continue through expected nonzero results. Do not copy that suffix into a deployment guard if you need comparison failure to stop the operation.
The function captures the comparison’s exit status inside the conditional before another command can replace it. Its final return preserves that status for a caller, even though printing a message would itself usually succeed. The outer demonstration finishes successfully after handling its examples; that final shell result is not the status of all three comparisons.
Use a guard that keeps errors separate
When adapting this approach to real regular files, decide what each branch permits. A match might allow the next validation step; a difference might require review; a read error should stop the comparison-dependent decision and prompt investigation. Do not automatically overwrite either input to make a failure disappear.
Quote both paths to preserve spaces, and use -- before filenames that could begin with a hyphen. A filename consisting of a single hyphen has special meaning to cmp: it denotes standard input. For a real local file with that name, specify an explicit path such as ./- instead.
Avoid pipelines that make you inspect a later command’s exit status instead of cmp’s. Also avoid placing a logging command between the comparison and status capture. The conditional pattern above keeps the important result next to the operation that produced it.
Know what matching bytes do not prove
A successful comparison concerns the file contents read during that operation. It does not compare ownership, permissions, timestamps or application meaning. Separate those checks when deciding whether a configuration is ready. If your question is whether two pathnames identify the same filesystem object, use the related tutorial on checking hard links with stat; identical bytes alone cannot answer that question.
Files actively being rewritten are poor comparison inputs. Coordinate a stable copy or application-supported snapshot first. Matching files are not independent backups merely because cmp returned zero, and matching bytes do not establish that either copy came from a trusted source.
Checklist and source
- Use stable, intended input paths.
- Read the exit status, not silence alone.
- Keep differences separate from comparison errors.
- Validate configuration semantics and metadata separately.
- Preserve originals while investigating unexpected results.
The GNU Diffutils manual source mirror, in its Invoking cmp and cmp Options sections, supports the status meanings and quiet-mode behaviour described here. This older source is used for stable command semantics, not release-version claims. This tutorial is educational: test before production use. The site owner is not responsible for misuse, damage, data loss or production issues.



