Mit xxd und od Hexdumps lesen, Magic Bytes prüfen und Dateiformate identifizieren
Wenn ein Upload fehlschlägt, ein Archiv beschädigt scheint oder ein Deployment-Skript die falsche Dateiart verarbeitet, hilft kein grafischer Hex-Editor so schnell weiter wie ein direkter Blick mit xxd oder od auf der Kommandozeile. Wer die ersten Bytes einer Datei lesen kann, erkennt Formate, Beschädigungen und Fehlkonfigurationen oft schneller als jedes automatische Werkzeug.
Inhaltsverzeichnis
- 1. Warum Binäranalyse auf der Kommandozeile in der Praxis unverzichtbar bleibt
- 2. xxd: der schnelle, gut lesbare Hexdump
- 3. od: POSIX-portabel und flexibel in der Ausgabeformatierung
- 4. Magic Bytes lesen: wie Dateiformate sich am Anfang zu erkennen geben
- 5. Das file-Kommando als schneller erster Check, mit Grenzen
- 6. Byte-Bereiche vergleichen und Beschädigungen lokalisieren
- 7. Binäranalyse in Deployment- und Upload-Pipelines automatisieren
- 8. Große Dateien nicht komplett einlesen: nur die relevanten Bytes prüfen
- 9. xxd, od und file im direkten Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum Binäranalyse auf der Kommandozeile in der Praxis unverzichtbar bleibt
Deployment-Skripte, Upload-Handler und Backup-Routinen bekommen es ständig mit Dateien zu tun, deren tatsächlicher Inhalt sich nicht auf den Dateinamen oder die deklarierte Endung verlassen lässt. Eine Datei mit der Endung .jpg kann in Wahrheit ein PNG sein, ein hochgeladenes Archiv kann mitten in der Übertragung abgebrochen sein, und ein Konfigurationsskript kann eine vermeintliche Textdatei erhalten, die in Wirklichkeit UTF-16-kodiert ist und deshalb wie Kauderwelsch aussieht.
In all diesen Fällen liefert ein direkter Blick auf die rohen Bytes am Dateianfang die Antwort schneller als jedes Raten anhand des Dateinamens. Werkzeuge wie xxd und od gehören seit Jahrzehnten zur Standardausstattung jedes Linux-Systems, brauchen keine grafische Oberfläche und lassen sich direkt in Bash-Skripte einbauen, um Dateien vor der weiteren Verarbeitung automatisch zu validieren.
2. xxd: der schnelle, gut lesbare Hexdump
xxd erzeugt eine Hexdump-Ansicht mit drei Spalten pro Zeile: dem Offset innerhalb der Datei, den Bytes in hexadezimaler Darstellung und rechts daneben derselben Zeile in druckbaren ASCII-Zeichen, wobei nicht druckbare Bytes als Punkt dargestellt werden. Diese kombinierte Ansicht macht xxd besonders angenehm zu lesen, weil sich Textabschnitte innerhalb einer Binärdatei sofort in der rechten Spalte zeigen, ohne die hexadezimalen Werte einzeln übersetzen zu müssen.
Für die meisten Debugging-Aufgaben reicht bereits xxd -l N datei, um nur die ersten N Bytes anzuzeigen, weil die für Formaterkennung relevanten Informationen fast immer ganz am Dateianfang stehen. Das vermeidet, eine potenziell riesige Datei komplett auszugeben, wenn nur der Header interessiert.
#!/usr/bin/env bash
set -euo pipefail
# Show the first 32 bytes as a classic hexdump
xxd -l 32 upload.bin
# 00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452 .PNG........IHDR
# 00000010: 0000 0100 0000 0100 0806 0000 0072 b83b .............r.;
# xxd can also reverse the process: turn a hexdump back into raw bytes
xxd -r -p <<< "89504e470d0a1a0a" > header.bin
3. od: POSIX-portabel und flexibel in der Ausgabeformatierung
od (octal dump) ist älter als xxd, in praktisch jeder POSIX-Umgebung garantiert vorhanden und deshalb die zuverlässigere Wahl, wenn ein Skript auf möglichst vielen Systemen laufen soll, auf denen xxd eventuell nicht installiert ist. Der Name ist historisch bedingt, denn od kann längst nicht nur oktal, sondern mit der Option -t x1 auch hexadezimal ausgeben, byteweise wie xxd.
Ein praktischer Vorteil von od gegenüber xxd ist die feingranulare Kontrolle über das Ausgabeformat mit der -t-Option: -t x1 für einzelne Hex-Bytes, -t d4 für vorzeichenbehaftete 32-Bit-Ganzzahlen, oder -t c für eine reine Zeichenansicht. Diese Flexibilität macht od besonders nützlich, wenn ein binäres Dateiformat bekannte numerische Felder an festen Offsets hat, die direkt als Zahl statt als Hex-Byte gelesen werden sollen.
#!/usr/bin/env bash
set -euo pipefail
# Same first bytes, POSIX-portable hexdump with od
od -A x -t x1z -v upload.bin | head -n 2
# 000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 >.PNG........IHDR<
# Read a 4-byte little-endian integer at a fixed offset as a decimal number
od -A none -j 16 -N 4 -t u4 upload.bin
4. Magic Bytes lesen: wie Dateiformate sich am Anfang zu erkennen geben
Die meisten binären Dateiformate beginnen mit einer festen Byte-Sequenz, der sogenannten Magic Number, die eindeutig auf das Format hinweist, unabhängig davon, wie die Datei benannt ist. PNG-Dateien beginnen immer mit 89 50 4e 47, ZIP-Archive mit 50 4b 03 04, und PDF-Dokumente mit den ASCII-Zeichen %PDF. Diese Sequenzen sind Teil der jeweiligen Formatspezifikation und ändern sich praktisch nie zwischen Versionen desselben Formats.
Ein Bash-Skript kann diese Magic Bytes direkt mit xxd oder od auslesen und gegen bekannte Signaturen vergleichen, um zu erkennen, ob eine hochgeladene Datei tatsächlich das ist, was sie vorgibt zu sein, ganz unabhängig von der übermittelten Dateiendung oder dem HTTP-Content-Type-Header, denen beide von einem Client frei manipuliert werden können. Diese Prüfung ist besonders wichtig für Upload-Handler, die niemals blind auf Client-Angaben vertrauen sollten.
#!/usr/bin/env bash
set -euo pipefail
detect_format() {
local file="$1"
local magic
magic=$(xxd -l 4 -p "$file")
case "$magic" in
89504e47) echo "PNG image" ;;
ffd8ffe*|ffd8ffdb) echo "JPEG image" ;;
504b0304) echo "ZIP archive (or DOCX/XLSX/JAR)" ;;
25504446) echo "PDF document" ;;
1f8b0800|1f8b0808) echo "gzip archive" ;;
*) echo "Unknown format: $magic" ;;
esac
}
detect_format "upload.bin"
5. Das file-Kommando als schneller erster Check, mit Grenzen
Das Kommando file nutzt intern genau diese Magic-Byte-Datenbank und liefert für die meisten gängigen Formate eine sofortige, gut lesbare Antwort, ohne dass ein Skript selbst Signaturen pflegen muss. Für einen schnellen ersten Check in einem Deployment-Skript ist file --mime-type -b datei deshalb häufig der pragmatischste Einstieg, weil es sowohl gängige Bildformate als auch Archive, ausführbare Dateien und Textkodierungen zuverlässig erkennt.
Die Grenzen von file zeigen sich bei proprietären oder sehr spezifischen Binärformaten, für die keine Signatur in der mitgelieferten Datenbank hinterlegt ist, oder wenn ein Skript nicht nur das grobe Format, sondern ein konkretes Feld an einem festen Offset auswerten muss, etwa eine Versionsnummer innerhalb eines eigenen Binärformats. In diesen Fällen bleibt der direkte Griff zu xxd oder od mit einem selbst definierten Offset die einzig verlässliche Lösung.
#!/usr/bin/env bash
set -euo pipefail
# Quick MIME-type check before deciding how to process an upload
mime=$(file --mime-type -b uploaded_file)
case "$mime" in
image/png|image/jpeg) echo "Processing as image" ;;
application/zip) echo "Processing as archive" ;;
*) echo "Rejected: unsupported type $mime" >&2; exit 1 ;;
esac
6. Byte-Bereiche vergleichen und Beschädigungen lokalisieren
Bei der Fehlersuche in beschädigten Dateien, etwa einem Backup, das nach der Übertragung nicht mehr entpackbar ist, hilft ein direkter Byte-für-Byte-Vergleich mit einer bekannten guten Kopie. cmp -l zeigt jeden abweichenden Byte-Offset zusammen mit den unterschiedlichen Werten in oktaler Darstellung, was in Kombination mit einem gezielten xxd-Aufruf auf genau diesen Offset erlaubt, die Abweichung im Kontext der umgebenden Bytes zu sehen.
Diese Technik ist besonders wertvoll, um zwischen einer vollständig zufälligen Beschädigung, etwa durch einen defekten Datenträger, und einer strukturierten Abweichung, etwa einem falsch konfigurierten Zeichensatz-Konverter, zu unterscheiden. Eine zufällige Beschädigung zeigt verstreute Einzelbyte-Unterschiede, während eine strukturierte Abweichung oft an denselben relativen Positionen in wiederkehrenden Mustern auftritt.
#!/usr/bin/env bash
set -euo pipefail
# List every differing byte offset between two files
cmp -l original.bin corrupted.bin | head -n 5
# Zoom into a specific offset (e.g. byte 1024) with 16 bytes of context
xxd -s 1016 -l 32 original.bin
xxd -s 1016 -l 32 corrupted.bin
7. Binäranalyse in Deployment- und Upload-Pipelines automatisieren
In einer automatisierten Deployment- oder Upload-Pipeline lohnt es sich, die Magic-Byte-Prüfung als eigenständige, wiederverwendbare Funktion an den Anfang jeder Verarbeitung zu stellen, statt sie nur bei Bedarf manuell durchzuführen. Eine solche Funktion validiert eine Datei, bevor irgendein weiterer Schritt wie Entpacken, Hochladen zu einem Storage-Bucket oder Weiterverarbeiten durch ein anderes Tool ausgeführt wird, und bricht bei einer unerwarteten Signatur kontrolliert ab, statt dem nachgelagerten Werkzeug eine kaputte Datei zu übergeben.
Diese Validierung sollte, genau wie andere Eingabeprüfungen, so früh wie möglich in der Pipeline stattfinden und eine klare, für Menschen lesbare Fehlermeldung erzeugen, die den erwarteten und den tatsächlich gefundenen Wert nennt. Das verkürzt die Fehlersuche erheblich, wenn ein automatisierter Lauf später fehlschlägt und jemand nachvollziehen muss, warum genau eine bestimmte Datei abgelehnt wurde.
8. Große Dateien nicht komplett einlesen: nur die relevanten Bytes prüfen
Sowohl xxd als auch od unterstützen Offset- und Längenbegrenzungen (-l/-s bei xxd, -N/-j bei od), die verhindern, dass ein Skript eine mehrere Gigabyte große Datei komplett liest, nur um die ersten paar Bytes am Anfang zu prüfen. Für eine reine Formaterkennung reichen fast immer die ersten 16 bis 64 Bytes aus, und ein Skript, das konsequent diese Begrenzungen nutzt, bleibt auch bei sehr großen Dateien in konstanter, kaum messbarer Laufzeit.
Wer stattdessen versehentlich die gesamte Datei durch xxd oder od schickt und die Ausgabe erst danach mit head begrenzt, liest trotzdem die komplette Datei von der Platte, weil die Begrenzung erst nach der vollständigen Verarbeitung greift. Diese unnötige I/O-Last summiert sich bei häufigen automatisierten Prüfungen auf viele Dateien schnell zu einem spürbaren Performance-Problem.
9. xxd, od und file im direkten Vergleich
Für die tägliche Fehlersuche ist xxd wegen seiner gut lesbaren, kombinierten Hex-und-ASCII-Ausgabe meist die angenehmste Wahl, während od als POSIX-Standardwerkzeug die verlässlichere Option für portable Skripte ist, die auch auf minimalen Systemen ohne xxd laufen müssen. Das Kommando file bleibt der schnellste Weg zu einer groben Formataussage, ersetzt aber keine gezielte Byte-Prüfung, sobald ein Skript ein konkretes, selbst definiertes Binärformat validieren muss.
| Werkzeug | Verfügbarkeit | Stärke | Typischer Einsatz |
|---|---|---|---|
xxd |
Meist vorinstalliert (vim-Paket) | Gut lesbare Hex+ASCII-Ansicht | Manuelles Debugging, schneller Hexdump |
od |
POSIX-Standard, überall vorhanden | Flexible Ausgabeformate (-t) | Portable Skripte, feste Feld-Offsets |
file |
Meist vorinstalliert | Sofortige Formataussage | Schneller MIME-Type-Check |
cmp -l |
POSIX-Standard | Byte-genauer Vergleich | Beschädigungen lokalisieren |
Mironsoft
Shell-Automatisierung, DevOps-Tooling und Deployment-Infrastruktur
Shell-Skripte, die in der Produktion zuverlässig laufen?
Wir analysieren bestehende Bash-Skripte, erkennen fragile Muster und ersetzen sie durch robuste Bash-Patterns: mit vollständiger Fehlerbehandlung, Logging und sicherer Parallelisierung für euren Deployment-Stack.
Code-Review
ShellCheck-Analyse und manuelle Prüfung auf kritische Bash-Pattern-Verstöße.
Refactoring
Fehlerbehandlung, Logging und sichere Dateioperationen nachrüsten.
CI-Integration
ShellCheck und BATS in Pipelines integrieren und Regressionstests aufbauen.
10. Zusammenfassung
Binärdaten in Bash untersuchen: Das Wichtigste auf einen Blick
Magic Bytes prüfen
Die ersten Bytes einer Datei mit xxd -l 4 -p auslesen und gegen bekannte Signaturen vergleichen, statt Dateiendung oder Content-Type zu vertrauen.
xxd vs. od
xxd für gut lesbares manuelles Debugging, od als POSIX-Standard für portable Skripte ohne Abhängigkeit vom vim-Paket.
Nur relevante Bytes lesen
Mit -l/-s bei xxd oder -N/-j bei od nur den Dateianfang prüfen, statt große Dateien komplett einzulesen.
Beschädigungen lokalisieren
cmp -l zeigt abweichende Offsets, ein gezielter xxd-Aufruf auf diesen Offset zeigt die Abweichung im Byte-Kontext.