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
diffaussteigt - Backup-Verifikation — nach
cpoderrsyncschnell prüfen, ob Quelle und Ziel identisch sind - Skripte — Exit-Code 0/1/2 ist eindeutig, mit
-släuftcmpkomplett 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.
cmp file1 file2file1 file2 differ: byte 42, line 3Mit -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:
cmp -l file1 file2 42 110 154
43 145 157
88 040 011Lesart: 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
| Option | Wirkung |
|---|---|
-l, --verbose | Alle Differenzen listen, nicht nur die erste |
-s, --silent, --quiet | Keine Ausgabe — nur Exit-Code (für Skripte) |
-i SKIP, --ignore-initial=SKIP | Erste SKIP Bytes überspringen (z. B. Header) |
-n LIMIT, --bytes=LIMIT | Maximal LIMIT Bytes vergleichen |
-b, --print-bytes | Byte-Werte zusätzlich als Zeichen ausgeben |
--help | Hilfe anzeigen |
--version | Version 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:
if cmp -s quelle.iso ziel.iso; then
echo "Backup identisch"
else
echo "Unterschied gefunden"
fiBackup-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:
cp -a daten/ /mnt/backup/daten/
find daten -type f -exec cmp -s {} /mnt/backup/{} \; -o -printDifferenzen zählen. -l produziert eine Zeile pro abweichendem Byte — über wc -l lässt sich die Anzahl direkt zählen:
cmp -l a.bin b.bin | wc -l17Header ü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:
cmp -i 44 a.wav b.wavcmp vs. diff
| Aspekt | cmp | diff |
|---|---|---|
| Granularität | Byte für Byte | Zeile für Zeile |
| Use-Case | Binär-Files, Skript-Checks | Text-Files, Code-Reviews, Patches |
| Geschwindigkeit | Sehr schnell (Default bricht beim ersten Diff ab) | Langsamer, lädt File für LCS-Algorithmus |
| Output | Erste Position oder alle Bytes | Hunks mit Kontext, mehrere Formate |
| Patch-fähig | Nein | Ja, 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
- cmp(1) – Linux manual page (man7.org) — offizielle Dokumentation aller cmp-Optionen
- GNU diffutils Manual: cmp invocation — ausführliches Kapitel im GNU-Handbuch
Verwandte Artikel
- diff – Files zeilenweise vergleichen — Das Pendant für Text-Files
- md5sum & sha256sum – Prüfsummen — Hash-basierter Identitäts-Check über viele Files
- file – Dateityp erkennen — Vor dem Vergleich klären, was vor dir liegt
- xxd – Hex-Dump erzeugen — Binärdaten in lesbaren Hex umwandeln
- hexdump – Bytes als Hex anzeigen — Klassische Alternative zu xxd