cmp ist das Byte-Werkzeug zum Vergleichen zweier Files. Während diff zeilenweise arbeitet und Text voraussetzt, geht cmp Byte für Byte durch — was es zur ersten Wahl für Binär-Files macht: Images, Archive, ausführbare Programme, Backups. Per Default meldet cmp nur die erste Abweichung und setzt einen Exit-Code, der sich in Skripten direkt nutzen lässt.

Was cmp macht

cmp liest zwei Files parallel und vergleicht jedes Byte. Stimmen alle Bytes überein und sind beide Files gleich lang, gibt es keine Ausgabe und Exit-Code 0. Bei der ersten Abweichung wird die Position gemeldet und das Programm beendet — schnell und speicherschonend, weil nicht das ganze File analysiert werden muss.

Das macht cmp ideal für:

  • Binär-Files — Images, ZIPs, Executables, wo diff aussteigt
  • Backup-Verifikation — nach cp oder rsync schnell prüfen, ob Quelle und Ziel identisch sind
  • Skripte — Exit-Code 0/1/2 ist eindeutig, mit -s läuft cmp komplett still
  • Image-Equality — zwei Disk-Images oder ISO-Files Byte-genau vergleichen
  • Patch-Verifikation — nach einem Binär-Patch prüfen, ob das Ergebnis dem Soll entspricht

Output erklärt

Per Default meldet cmp die erste abweichende Position — als Byte-Offset (1-basiert) und als Zeilennummer der Zeile, in der das Byte liegt.

Bash Default-Output
cmp file1 file2
Output
file1 file2 differ: byte 42, line 3

Mit -l (long) hört cmp nicht beim ersten Unterschied auf, sondern listet alle abweichenden Bytes — jeweils Offset, Byte-Wert in File 1, Byte-Wert in File 2, jeweils oktal:

Bash Alle Differenzen
cmp -l file1 file2
Output
 42 110 154
 43 145 157
 88 040 011

Lesart: An Byte 42 steht in File 1 0o110 (= H), in File 2 0o154 (= l). Die Werte sind oktal, was anfangs ungewohnt ist; mit -b werden zusätzlich die ASCII-Repräsentationen ausgegeben.

Optionen

OptionWirkung
-l, --verboseAlle Differenzen listen, nicht nur die erste
-s, --silent, --quietKeine Ausgabe — nur Exit-Code (für Skripte)
-i SKIP, --ignore-initial=SKIPErste SKIP Bytes überspringen (z. B. Header)
-n LIMIT, --bytes=LIMITMaximal LIMIT Bytes vergleichen
-b, --print-bytesByte-Werte zusätzlich als Zeichen ausgeben
--helpHilfe anzeigen
--versionVersion anzeigen

-i und -n lassen sich kombinieren — etwa um nur einen bestimmten Bereich zu prüfen: cmp -i 100 -n 4096 a.bin b.bin vergleicht 4096 Bytes ab Offset 100. Mit zwei Werten in der Form SKIP1:SKIP2 darf man sogar in beiden Files an unterschiedlichen Positionen starten.

Praxis

Identitäts-Check im Skript. -s macht cmp komplett still, der Exit-Code reicht für eine if-Bedingung:

Bash Silent-Check
if cmp -s quelle.iso ziel.iso; then
    echo "Backup identisch"
else
    echo "Unterschied gefunden"
fi

Backup-Verifikation nach rsync oder cp. Wenn die Hashes egal sind und es nur um die Byte-Identität geht, ist cmp schneller als sha256sum, weil es bei der ersten Abweichung abbricht:

Bash Backup verifizieren
cp -a daten/ /mnt/backup/daten/
find daten -type f -exec cmp -s {} /mnt/backup/{} \; -o -print

Differenzen zählen. -l produziert eine Zeile pro abweichendem Byte — über wc -l lässt sich die Anzahl direkt zählen:

Bash Differenzen zählen
cmp -l a.bin b.bin | wc -l
Output
17

Header überspringen. Bei Files mit variablem Header (Timestamps in PNG, Metadata in WAV) kannst du den Header-Bereich mit -i überspringen und nur den Payload vergleichen:

Bash Header überspringen
cmp -i 44 a.wav b.wav

cmp vs. diff

Aspektcmpdiff
GranularitätByte für ByteZeile für Zeile
Use-CaseBinär-Files, Skript-ChecksText-Files, Code-Reviews, Patches
GeschwindigkeitSehr schnell (Default bricht beim ersten Diff ab)Langsamer, lädt File für LCS-Algorithmus
OutputErste Position oder alle BytesHunks mit Kontext, mehrere Formate
Patch-fähigNeinJa, via Unified-Format und patch

Faustregel: Für Text ist diff ergonomischer, weil es Zeilen, Kontext und Patch-Format kennt. Für Binär ist cmp das einzige sinnvolle Tool — diff schaltet bei NUL-Bytes auf Binary files ... differ um und liefert keine Details. Wenn du nur wissen willst, ob zwei Files identisch sind, ist cmp -s schneller als diff -q, weil es nicht in Zeilen denken muss.

Besonderheiten

Exit-Code 0, 1, 2 — sauber für Skripte

Wie diff setzt cmp drei klar getrennte Exit-Codes: 0 wenn die Files Byte-identisch sind, 1 wenn sie sich unterscheiden, 2 bei einem echten Fehler (Datei fehlt, kein Lesezugriff). Damit lässt sich Fehlerbehandlung sauber von echten Inhaltsunterschieden trennen — cmp -s a b; case $? in 0) ... ;; 1) ... ;; 2) ... ;; esac ist ein robustes Pattern, das viele andere Vergleichstools nicht zulassen.

Mit -l und Pipe Differenzen zählen

cmp -l a b | wc -l liefert die Anzahl der abweichenden Bytes — ohne dass du selbst parsen musst. Das ist nützlich, um zu entscheiden, ob ein File „fast identisch” oder „komplett anders” ist: ein paar Bytes Differenz deuten oft auf einen Timestamp oder eine Versionsnummer hin, Tausende auf einen kompletten Re-Build oder Re-Compile.

`-s` für stille Skripte — kein Rauschen in Logs

Ohne -s schreibt cmp bei Unterschieden eine Zeile auf stdout. In automatisierten Setups (Cron, CI) verschmutzt das die Logs unnötig. Mit -s läuft cmp komplett still und kommuniziert ausschließlich über den Exit-Code. Diese Disziplin ist gerade in Pipelines wichtig: stdout/stderr sauber halten und Logik über Exit-Codes steuern.

Fehlende Files sind Fehler, nicht Difference

Wenn eines der angegebenen Files nicht existiert oder nicht lesbar ist, liefert cmp Exit-Code 2 und nicht 1. Das wirkt im ersten Moment kontraintuitiv — „die Files sind ja unterschiedlich, weil eines fehlt” — ist aber konsequent: cmp unterscheidet zwischen Files konnten verglichen werden und sind unterschiedlich und Vergleich war nicht möglich. In Skripten solltest du Exit-Code 2 separat abfangen, sonst maskierst du echte Pfad- oder Permission-Probleme als reine Inhaltsunterschiede.

byte-Counter und line-Counter laufen unabhängig

Die Meldung byte 42, line 3 heißt: das 42. Byte weicht ab, und es liegt in Zeile 3. Der line-Counter zählt dabei die \n-Bytes, die cmp bisher gesehen hat — Zeile 3 ist also die mit dem ersten unterschiedlichen Byte, nicht zwingend die Zeile, in der mehr als ein Byte differiert. Bei reinen Binär-Files ohne Zeilenumbrüche bleibt die line-Anzeige bei 1 — das ist kein Bug, sondern die Logik dahinter.

Längenunterschied wird separat gemeldet

Sind die Files bis zum Ende des kürzeren identisch, das längere File hat aber zusätzlichen Inhalt, meldet cmp: cmp: EOF on file1 after byte N, in line L. Dieses Verhalten ist subtil und in Skripten wichtig — der Exit-Code ist 1 wie bei jedem Unterschied, aber die Meldung sagt explizit, dass der Unterschied ein Längen-Unterschied ist. Bei Backup-Verifikationen ist das oft die wichtigste Information: ein File wurde abgeschnitten oder erweitert.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Textverarbeitung

Zur Übersicht