⌨️Werkzeuge: PDF auf der Kommandozeile
Alle Ausgaben sind echt – erzeugt mit der Beispiel-PDF dieser App (hello.pdf, im Byte-Explorer herunterladbar). So lässt sich alles nachprüfen.
Strukturwerkzeug: prüft, zerlegt, verschlüsselt, linearisiert – ändert keine Inhalte.
pdfinfo, pdftotext, pdfimages, pdffonts … – Bibliothek hinter vielen Linux-Betrachtern.
mutool show/clean/draw – schlanker Renderer und Werkzeugkasten von Artifex.
PostScript- und PDF-Interpreter: rendert, konvertiert, erzeugt PDF/A.
$ qpdf --check hello.pdfLiest die ganze Datei über xref und Trailer, dekodiert alle Streams und meldet Strukturfehler.
checking hello.pdf PDF Version: 1.7 File is not encrypted File is not linearized No syntax or stream encoding errors found; the file may still contain errors that qpdf cannot detect
$ qpdf --show-xref hello.pdfDie aufgelöste Cross-Reference-Tabelle: Objekt/Generation und Byte-Offset – dieselben Zahlen wie im Byte-Explorer.
1/0: uncompressed; offset = 15 2/0: uncompressed; offset = 64 3/0: uncompressed; offset = 121 4/0: uncompressed; offset = 250 5/0: uncompressed; offset = 341 6/0: uncompressed; offset = 411
$ qpdf --show-object=3 hello.pdfEin einzelnes Objekt, normalisiert (Schlüssel sortiert).
<< /Contents 4 0 R /MediaBox [ 0 0 300 144 ] /Parent 2 0 R /Resources << /Font << /F1 5 0 R >> >> /Type /Page >>
$ qpdf --show-object=4 --filtered-stream-data hello.pdfStream-Inhalt nach Anwendung aller Filter (bei FlateDecode also entpackt).
BT /F1 24 Tf 72 72 Td (Hello World) Tj ET
$ qpdf --qdf --object-streams=disable hello.pdf hello-qdf.pdfQDF-Modus: eine Datei zum Bearbeiten im Texteditor – Objekte neu nummeriert, eingerückt, Streams entpackt, /Length als eigenes Objekt. Nach dem Editieren repariert „fix-qdf“ die Offsets.
%PDF-1.7
%¿÷¢þ
%QDF-1.0
%% Original object ID: 1 0
1 0 obj
<<
/Pages 3 0 R
/Type /Catalog
>>
endobj
%% Original object ID: 6 0
2 0 obj
<<
/Producer (VisualPdf)
/Title (Hello World)
>>
endobj
%% Original object ID: 2 0
3 0 obj
<<
/Count 1
/Kids [
4 0 R
]
/Type /Pages
>>
endobj
%% Page 1
%% Original object ID: 3 0
4 0 obj
<<
/Contents 5 0 R
/MediaBox [
0
0
300
144
]
/Parent 3 0 R
/Resources <<
/Font <<
/F1 7 0 R
>>
>>
/Type /Page
>>
endobj
%% Contents for page 1
%% Original object ID: 4 0
5 0 obj
<<
/Length 6 0 R
>>
stream
BT
/F1 24 Tf
72 72 Td
(Hello World) Tj
ET
endstream
endobj
%QDF: ignore_newline
6 0 obj
41
endobj
%% Original object ID: 5 0
7 0 obj
<<
/BaseFont /Helvetica
/Subtype /Type1
/Type /Font
>>
endobj
xref
0 8
0000000000 65535 f
0000000052 00000 n
0000000133 00000 n
0000000229 00000 n
0000000338 00000 n
0000000561 00000 n
0000000679 00000 n
0000000725 00000 n
trailer <<
/Info 2 0 R
/Root 1 0 R
/Size 8
/ID [<d666…2f48><d666…2f48>]
>>
startxref
802
%%EOF$ qpdf --linearize hello.pdf lin.pdf && qpdf --check-linearization lin.pdfSortiert die Datei für „Fast Web View“ um und prüft das Ergebnis (siehe Seite Updates & Streams).
lin.pdf: no linearization errors
$ qpdf --show-encryption --password=beispiel-user enc.pdfVerschlüsselungsparameter einer mit AES-256 geschützten Kopie (beispiel-user ist ein Beispielpasswort).
R = 6 P = -4 User password = beispiel-user Supplied password is user password extract for accessibility: allowed extract for any purpose: allowed print low resolution: allowed print high resolution: allowed modify document assembly: allowed modify forms: allowed modify annotations: allowed modify other: allowed modify anything: allowed stream encryption method: AESv3 string encryption method: AESv3 file encryption method: AESv3
$ pdfinfo hello.pdfMetadaten aus dem Info-Dictionary und Eckdaten der Datei. „Optimized“ = linearisiert.
Title: Hello World Producer: VisualPdf Custom Metadata: no Metadata Stream: no Tagged: no UserProperties: no Suspects: no Form: none JavaScript: no Pages: 1 Encrypted: no Page size: 300 x 144 pts Page rot: 0 File size: 690 bytes Optimized: no PDF version: 1.7
$ pdftotext -layout hello.pdf -Extrahiert den Text. Das klappt nur, weil der Leser die Bytes des Strings über die Kodierung der Schrift in Zeichen zurückübersetzen kann.
Hello World
$ mutool show hello.pdf trailerZeigt den Trailer – oder mit einer Nummer ein beliebiges Objekt.
trailer << /Size 7 /Root 1 0 R /Info 6 0 R >>
$ mutool show hello.pdf xrefDie xref-Tabelle mit vorangestellter Objektnummer.
xref 0 7 00000: 0000000000 65535 f 00001: 0000000015 00000 n 00002: 0000000064 00000 n 00003: 0000000121 00000 n 00004: 0000000250 00000 n 00005: 0000000341 00000 n 00006: 0000000411 00000 n
$ mutool show hello.pdf grepAlle Objekte kompakt, eines pro Zeile – ideal für grep.
1 0 obj <</Pages 2 0 R/Type/Catalog>> 2 0 obj <</Count 1/Kids[3 0 R]/Type/Pages>> 3 0 obj <</Contents 4 0 R/MediaBox[0 0 300 144]/Parent 2 0 R/Resources<</Font<</F1 5 0 R>>>>/Type/Page>> 4 0 obj <</Length 41>> stream 5 0 obj <</BaseFont/Helvetica/Subtype/Type1/Type/Font>> 6 0 obj <</Producer(VisualPdf)/Title(Hello World)>> trailer <</Size 7/Root 1 0 R/Info 6 0 R>>
$ mutool show hello.pdf pagesWelches Objekt ist welche Seite?
page 1 = 3 0 R
$ gs -dNOPAUSE -dBATCH -sDEVICE=png16m -r144 -o hello.png hello.pdfRendert die Seite als PNG (144 dpi → 600 × 288 Pixel). Helvetica ist nicht eingebettet – Ghostscript ersetzt sie durch die metrisch gleiche Nimbus Sans.
GPL Ghostscript 10.08.0 (2026-09-08) Copyright (C) 2026 Artifex Software, Inc. All rights reserved. This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY: see the file COPYING for details. Processing pages 1 through 1. Page 1 Loading font Helvetica (or substitute) from …/Resource/Font/NimbusSans-Regular
$ gs -q -dNOPAUSE -dBATCH -sDEVICE=txtwrite -o - hello.pdfTextausgabe mit Ghostscripts eigenem Interpreter; die Einrückung bildet die x-Position 72 pt nach.
Hello World
💡Typische Arbeitsabläufe
qpdf --qdf --object-streams=disable in.pdf lesbar.pdf und dann im Editor lesen. Komprimierte Streams und Object Streams sind danach Klartext.qpdf defekt.pdf repariert.pdf baut die xref-Tabelle neu auf – falsche Offsets verschwinden. Warnungen zeigen, was repariert wurde.apt install qpdf poppler-utils mupdf-tools ghostscript · macOS: brew install qpdf poppler mupdf ghostscript