Diff-Helfer im Überblick (Teil 2)

Aus LinuxUser 12/2021

Diff-Helfer im Überblick (Teil 2)

© wabeno / 123RF.com

Herausragend

Für viele Datenformate gibt es spezialisierte Differ, die Vergleiche erleichtern und Unterschiede zwischen Dateien hervorheben. Sie eignen sich für eine Vielzahl von Anwendungsfällen.

Das Standardkommando diff kennt jeder, der schon einmal ein wenig programmiert hat. Es zeigt Unterschiede zwischen zwei Dateien an, etwa zwischen zwei Versionen eines Skripts. Aufgrund der Schlichtheit muss man es und seine Ausgabe nicht unbedingt mögen, aber es gehört zum Unix-Linux-Grundwissen einfach dazu.

In Teil 1 dieser Serie [1] standen Diff und seine simpleren Verwandten im Mittelpunkt. Dabei kamen insbesondere die unterschiedlichen Ausgabeformate mit und ohne farbliche Hervorhebung der Unterschiede zwischen zwei oder mehr (Text-)Dateien zur Sprache. Allerdings eignen sich die Standard-Differ nicht für alle Dateiformate. Deshalb geht es diesmal um Werkzeuge, die auf spezielle, strukturierte (Text-)Formate sowie Archive zugeschnitten sind und mit diesen besonders gut umgehen können. Damit gelingt es Ihnen leichter, Unterschiede in CSV-, XML- und JSON-Daten zu entdecken.

Ähnlich wie bei einer Suche nach Alternativen oder Ergänzungen zu Grep löste das Rechercheergebnis bei den Autoren sowohl Begeisterung, als auch Besorgnis hervor. Die Fülle an Tools wuchs mit jedem zusätzlichen Rechercheschritt weiter an und erfreut zwar einerseits, wirkt aber andererseits schon fast erdrückend. Unsere Liste an Werkzeugen dürfte immer noch Lücken aufweisen, und wir sind daher auf spannende Überraschungen zum Thema eingestellt.

Zunächst haben wir die einzelnen Werkzeuge klassifiziert und danach in der Tabelle “Spezial-Differ im Überblick” gegenübergestellt. Die Spalte “Bedienoberfläche” enthält die Angabe CLI für Kommandozeilenwerkzeug (“command-line interface”), GUI für grafische Benutzeroberfläche (“graphical user interface”) und HTML für eine Ausgabe im Webbrowser.

Kategorie

Bedienoberfläche

Werkzeuge

Archive allgemein

CLI

Diffoscope, Adiff (aus atool)

Binärdateien

CLI

Diffoscope, Bsdiff, Rdiff, Vbindiff, Xdelta, Xdelta3

BZIP2-komprimiert

CLI

Diffoscope, Adiff, Bzdiff (aus bzip2), Zdiff (aus zutils)

CSV-Daten

CLI

Csvdiff, Numdiff

Git

CLI, GUI

Gitk, Git diff

GZIP-komprimiert

CLI

Diffoscope, Adiff, Zdiff (aus gzip), Zdiff (aus zutils)

ISO-Images

CLI

Diffoscope

JAR-Archive

CLI

Diffoscope, Jardiff (aus libdiffutils-java)

JSON-Dateien

CLI

Json-diff (aus haskell-aeson-diff-utils), Jsondiff (via Pip)

LaTeX-Dateien

CLI

Latexdiff

Meta

CLI, TUI, HTML

Diffoscope, Trydiffoscope

Paketverwaltung

CLI

Diffoscope, Debdiff (aus devscripts), Pkgdiff

PDF-Dokumente

GUI

Comparepdf, Diffpdf, Diff-pdf, Pdf-diff (via Pip)

PostgreSQL-Schemas

CLI

Apgdiff

RFCs

CLI

Rfcdiff

TAR-Archive

CLI

Diffoscope, Adiff, Pkgdiff, Tardiff

Verzeichnisse

GUI

Dirdiff, Mgdiff, Rmgdiff (aus mgdiff)

XML

CLI

Xmldiff

XZ-komprimiert

CLI

Diffoscope, Adiff, Xzdiff (aus xz-utils)

Zeitzonen

CLI

Tzdiff

Zip-Archive

CLI

Diffoscope, Adiff, Zipcmp

Komprimiertes

Bei Archiven erschweren zwei Aspekte den Vergleich: die Komprimierung und das Packen mehrerer Dateien in eine Datei. Während kompressionsspezifische Differ wie Bzdiff oder Xzdiff nur die jeweilige Kompression kennen, beherrschen generelle Differ für Archive meist alle wichtigen Komprimierungen.

Kompressionsspezifische Differ wie Zdiff, Bzdiff und Xzdiff stellen wir nur kurz vor, denn sie machen nicht viel anderes, als die als Parameter übergebenen Dateien bei Bedarf zu entpacken und dann den Klartext mit Diff zu vergleichen. Bei unkomprimierten Dateien als Parameter tun sie also exakt dasselbe wie Diff.

Die einzige zusätzliche Funktionalität, die sowohl Zdiff, Bzdiff als auch Xzdiff bieten: Man gibt nur eine einzelne komprimierte Datei als Parameter an und lässt sie dann automatisch gegen das unkomprimierte Pendant gleichen Namens (also ohne die Kompressionsendung) vergleichen. Zdiff und Bzdiff können das auch unter Angabe einer nicht komprimierten Datei. Sie ziehen dann die passende komprimierte Datei zum Abgleich heran. Xzdiff kann das nicht, da es neben XZ auch noch das Vorgängerformat LZIP beherrscht. Deswegen braucht es bei nur einem Parameter zwingend die komprimierte Datei, um zu wissen, welches Kompressionsformat als Basis dienen soll.

Aber was nun, wenn Sie zwei in unterschiedlichen Formaten komprimierte Dateien vergleichen möchten? Dieses Problem löst die Programmsammlung Zutils [2] recht elegant. Sie bietet eine Reihe von Tools, die denselben Programmnamen tragen wie die entsprechenden Hilfswerkzeuge von Gzip (wie etwa Zcat, Zdiff oder Zgrep), versteht aber transparent diverse Komprimierungsverfahren (momentan GZIP, BZIP2, LZIP und XZ). Damit müssen Sie gar nicht mehr nachdenken, welches Tool oder welchen Kommandozeilenschalter Sie jetzt für eine komprimierte Datei verwenden müssen. Ein Aufruf wie in Listing 1 funktioniert sofort ohne intensives Kopfkratzen.

Listing 1

Vergleich mit Zdiff

$ zdiff bar.bz2 foo.xz
1c1
< bar
---
> foo

Damit Sie diesen Vorteil auch einfach nutzen können, benennt das Paket zutils in Debian, Ubuntu und Derivaten die entsprechenden Programme aus dem Paket gzip um und setzt die eigenen Tools an deren Stelle. Die arbeiten aber komplett abwärtskompatibel zu denen von Gzip, sodass sie sich keinerlei Sorgen machen müssen, dass deswegen die gewohnten Aufrufe oder irgendwelche Skripte nicht mehr funktionieren.

Archiviertes

Bei Archiven, die mehrere Dateien oder Ordner umfassen, gestaltet sich die Sache etwas komplizierter. Einerseits erfolgt je nach Archivformat das Zusammenfassen der Dateien in ein File sowie die Komprimierung unabhängig voneinander. Die resultierenden Archive tragen dann Endungen wie tar.gz oder tar.bz2. Dabei steht tar für ein Archiv im TAR-Format und gz beziehungsweise bz2 für die auf das unkomprimierte Archiv angewendete Komprimierung. Andere Formate wie zum Beispiel ZIP und RAR erledigen Archivierung und Komprimierung hingegen in einem Aufwasch.

Andererseits enthalten Archive meist mehrere Dateien, oft auch noch in Unterverzeichnissen. Dabei möchte man gelegentlich zwei Archivdateien vergleichen, deren Inhalt sich zwar ähnelt, bei denen aber das oberste in der Archivdatei enthaltene Verzeichnis anders heißt – typisch etwa für Softwareprojekte, bei denen der Verzeichnisname die Versionsnummer enthält. Listing 2 zeigt als Beispiel Zutils in den Versionen 1.9 und 1.10. Zum Betrachten des Verzeichnisinhalts diente das Tool Als aus dem Paket atool (Archiv-Tool), auf das wir später noch genauer eingehen. So lange wir es nicht anderweitig erwähnen, verwenden alle im Folgenden genannten Archiv-Differ diese Methodik.

Listing 2

Inhalte der zutil*-Archive

$ als zutils_1.9.orig.tar.xz
drwxr-xr-x daniel/daniel     0 2020-07-03 19:55 zutils-1.9/
-rw-r--r-- daniel/daniel 14280 2020-05-15 17:58 zutils-1.9/zcat.cc
-rw-r--r-- daniel/daniel  3580 2020-04-30 18:02 zutils-1.9/arg_parser.h
[...]
$ als zutils_1.10.orig.tar.xz
drwxr-xr-x daniel/daniel     0 2021-01-27 17:15 zutils-1.10/
-rw-r--r-- daniel/daniel  2607 2021-01-05 12:57 zutils-1.10/rc.h
-rw-r--r-- daniel/daniel  8896 2021-01-05 12:57 zutils-1.10/zutils.cc
[...]

Dateilisten vergleichen

Der sehr einfache Archiv-Differ Tardiff zeigt nicht an, welche Dateiinhalte sich genau geändert haben, sondern stellt lediglich die Unterschiede zwischen den Inhaltsverzeichnissen der Archive dar. Sie sehen also, ob Dateien hinzukamen oder verschwunden sind. Mit dem Schalter -m zeigt Tardiff dann auch, welche Dateien sich verändert haben, aber nicht, was sich darin geändert hat. Fügen Sie zusätzlich den Schalter -s hinzu, sehen Sie auch noch die Änderungsstatistik pro Datei (Listing 3).

Listing 3

Tardiff

$ tardiff -m -s zutils_1.9.orig.tar.xz zutils_1.10.orig.tar.xz
/ ChangeLog        (  13 + /  5 -)
/ INSTALL          (   7 + /  1 -)
/ NEWS             (   6 + / 33 -)
/ README           (   1 + /  1 -)
/ arg_parser.cc    (   1 + /  1 -)
[...]

Die Idee hinter Tardiff besteht darin, bei Softwareprojekten eine einfache Qualitätskontrolle vor der Veröffentlichung zu ermöglichen: Sind alle neuen Dateien mit dabei? Enthält der Release-Tarball aus Versehen Dateien, die nicht hineingehören? Fehlen irrtümlicherweise Dateien gegenüber dem vorherigen Release? Mit Tardiff lassen sich solche Fragen schnell beantworten.

Ähnlich wie Tardiff, aber für ZIP-Archive und davon abgeleitete Formate, funktioniert das Programm Zipcmp [3] aus der Bibliothek Libzip. Es zeigt zudem noch Dateigrößen und Prüfsummen der Dateien an, die sich geändert haben, neu hinzukamen oder entfernt wurden. In Listing 4 sehen Sie, dass sich zwischen den beiden ZIP-Dateien der Inhalt der Datei foo geändert hat (andere Dateigröße und Prüfsumme), die Datei regionen1 entfiel (Minuszeichen davor) und dafür die Datei regionen3 hinzukam (Pluszeichen).

Listing 4

Zipcmp

$ zipcmp A.zip B.zip
--- A.zip
+++ B.zip
+       4 7e3265a8 foo
-       8 98ac8382 foo
-      40 70b20a60 regionen1
+      39 2d035157 regionen3

Dateiinhalte vergleichen

Genau spezifizierte Unterschiede zwischen den Inhalten nahezu beliebiger Archivformate fördert dagegen das Tool Adiff aus der Programmsammlung Atool [4] zutage. Das bereits in LU 08/2008 angetestete Paket [5] unterstützt eine Vielzahl verschiedener Archiv- und Paketformate sowie Kombinationen aus Archiv- und Kompressionsformaten. Dazu zählen unter anderem die Archivformate TAR, ZIP, JAR, RAR, 7ZIP, AR (.a), CAB (Windows Cabinet) und CPIO, die Paketformate DEB und RPM sowie die Kompressionsformate GZIP, BZIP, BZIP2, Compress (.Z), LZMA, LZOP, LZIP, XZ, RZIP und LRZIP. Hinzu kommen diverse eher historische Formate wie zum Beispiel ARC, ARJ, ACE und LHA. Allerdings unterstützt Atool nicht immer alle Funktionen der betreffenden Kompressions- und Archivformate. Details dazu finden Sie in der Dokumentation von Atool.

Insgesamt erinnert Atool sehr an Zutils, liefert es doch ebenfalls für einige Unix-Befehle Varianten, die auf Archiven funktionieren, und setzt in deren Namen einfach den Buchstaben “a” (statt “z”) davor. Das Tool Als haben Sie in Listing 2 bereits in Aktion gesehen. Es dient quasi als Ls für Archive und lässt sich wesentlich einfacher merken und tippen als zum Beispiel tar tvJf. Weitere enthaltene Tools mit Unix-Vorbildern sind Acat und Adiff. Dazu kommen noch die Tools Apack und Aunpack (die Namen sprechen für sich) sowie Arepack zum Konvertieren von einem Archivformat in ein anderes.

Uns interessiert hier aber vor allem das Tool Adiff. Wendet man es auf die bereits oben als Beispiel genutzten zwei Versionen von Zutils an, zeigt es genau das, was man erwartet – mit Ausnahme von zwei Verzeichnisnamen, die darauf hindeuten, wie es funktioniert: Es packt beide Archive in temporäre Verzeichnisse aus und lässt dann Diff diese beiden Verzeichnisse vergleichen (siehe Listing 5).

Listing 5

Adiff

$ adiff zutils_1.9.orig.tar.xz zutils_1.10.orig.tar.xz | head -10
diff -ru Unpack-4452/zutils-1.9/ChangeLog Unpack-8208/zutils-1.10/ChangeLog
--- Unpack-4452/zutils-1.9/ChangeLog    2020-06-27 00:17:50.000000000 +0200
+++ Unpack-8208/zutils-1.10/ChangeLog   2021-01-05 12:57:48.000000000 +0100
@@ -1,12 +1,20 @@
+2021-01-05  Antonio Diaz Diaz  <antonio@gnu.org>
+
+   * Version 1.10 released.
+   * zdiff.cc (set_fifonames): Encode pid in little endian order.
+   * zupdate.cc (zupdate_file): Fix a portability issue with Solaris 10.
+   * zutils.texi: Document that 'zgrep -L' fails with GNU grep 3.2 to 3.4.
[...]

Bekommt Adiff (oder eines der anderen Tools aus der Sammlung Atool) eine Datei ohne zum Format gehörende Dateiendung, so versucht es das Format anhand des Inhalts zu erkennen. Das hilft nicht immer weiter, weil sich oft das aufgerufene Entpacker-Tool weigert, eine Datei ohne passende Endung zu dekomprimieren. Das kennt man etwa von Gzip, wo die Manpage dieses Verhalten als bekannten Fehler dokumentiert.

Bei ineinander geschachtelten Archiven streckt allerdings auch Adiff die Waffen. Hierzu müssen Sie die große Keule herausholen – dazu später mehr.

PDF-Dokumente vergleichen

Bereits 2015 stellten wir in einem Artikel Comparepdf und Diffpdf vor [11]. Beide Werkzeuge erfuhren seitdem keine Weiterentwicklung mehr, die letzten Veröffentlichungen stammen aus den Jahren 2012 und 2013. Bei der Suche nach aktuelleren Alternativen tauchten Diff-pdf [12] und Pdf-diff [13] auf, die deren Entwickler zumindest noch pflegen. Pakete liegen allerdings nur für nicht mehr ganz taufrische Versionen von Ubuntu und Fedora vor. Diff-pdf müssen Sie also aus den Quellen übersetzen, das Python-Tool Pdf-diff installieren Sie am besten via Pip.

JSON

Als Ausgangspunkt für Vergleiche dienen uns im Folgenden zwei Varianten eines Buchbestands mit jeweils drei Büchern als JSON-Dateien, siehe Listing 6 und Listing 7. Diese klopfen wir mit dem Tool Jsondiff auf Unterschiede ab [6]. Das in Python geschriebene Jsondiff unterliegt der MIT-Lizenz und steht sowohl auf Github als auch via PyPI zur Verfügung. Paketiert wurde es bislang scheinbar noch nicht.

Listing 6

inventar-buchbestand1.json

{"book": [
  {
    "author": "Stephen Fry",
    "title": "The Hippopotamus",
    "publication": "1994"
  },
  {
    "author": "Ian Rankin",
    "title": "Set In Darkness",
    "publication": "2009"
  },
  {
    "author": "Ken Follett",
    "title": "The Pillars of the Earth",
    "publication": "1989"
  }
]}

Listing 7

inventar-buchbestand2.json

{"book": [
  {
    "author": "Stephen Fry",
    "title": "The Hippopotamus",
    "publication": "1994"
  },
  {
    "author": "Ian Rankin",
    "title": "Set In Darkness",
    "publication": "2009"
  },
  {
    "author": "Simon Beckett",
    "title": "Written In Bone",
    "publication": "2007"
  }
]}

Beide JSON-Dateien unterscheiden sich lediglich im letzten Datensatz: Dort flog Ken Follett aus der Bibliothek und Simon Beckett kam hinzu. Setzen Sie Jsondiff darauf an, liefert es den Unterschied als JSON-Datensatz in Form eines Einzeilers zurück. Ergänzen Sie den Befehl noch um das Kommando jq -C ., dann färbt Jq die Ausgabe ein, wodurch sich das Ergebnis besser lesen lässt. Listing 8 zeigt den Aufruf und das Vergleichsergebnis.

Listing 8

Jsondiff

$ jsondiff inventar-buchbestand*.json | jq -C .
{
  "book": {
    "2": {
      "title": "The Pillars of the Earth",
      "author": "Ken Follett",
      "publication": "1989"
    }
  }
}

Alleskönner

In der Tabelle “Spezial-Differ im Überblick” taucht ein Werkzeug sehr häufig auf: Diffoscope [7]. Es entstammt dem Reproducible-Builds-Projekt [8], das es sich zum Ziel gesetzt hat, einen unabhängig nachvollziehbaren Pfad vom Quell- zum Binärcode von Software bereitzustellen. Hier kommt es darauf an, herauszufinden, warum und an welcher Stelle sich zwei unter identischen Bedingungen gebaute Programme oder Softwarepakete unterscheiden.

Deswegen analysiert Diffoscope Dateien unterschiedlichster Formate einschließlich verschachtelter Archive und zeigt die Unterschiede zwischen ihnen an, und das nicht nur als unterschiedliche Bits und Bytes, sondern menschenlesbar geparst. Der Kasten “Diffoscope: Vergleichsformate” fasst die wichtigsten von Diffoscope unterstützten Formate zusammen.

Diffoscope: Vergleichsformate

  • Android-APK-Dateien und Boot-Images
  • Berkeley-DB-Datenbanken
  • Abbilder von Coreboot-Dateisystemen
  • Debian .buildinfo– und .changes-Dateien
  • Debian-Quellpakete (.dsc)
  • Binärdateien im ELF-Format
  • Git-Repositories
  • ISO-9660-CD-Abbilder
  • MacOS-Binärdateien
  • OpenSSH-Public-Keys
  • OpenWRT-Paketarchive (.ipk)
  • Mit PGP signierte und verschlüsselte Nachrichten
  • PDF- und Postscript-Dateien
  • RPM-Pakete
  • PNG-Bilder

Im Beispiel aus Abbildung 1 vergleichen wir zwei ZIP-Dateien miteinander, die ihrerseits jeweils eine weitere Archivdatei im TAR-Format enthalten. Der Tarball enthält seinerseits eine Textdatei mit kleinen Änderungen. Diffoscope zeigt nicht nur, dass sich die TAR-Archive unterscheiden, sondern offenbart den Unterschied auch als Diff – und das noch schön eingerückt, sodass man sofort erkennt, wo im verschachtelten Archiv sich die Unterschiede befinden. Als Sahnehäubchen färbt Diffoscope die Terminalausgabe bunt ein.

Abbildung 1: Rekursiv verschachtelte Archivdateien, mit Diffoscope verglichen.

Abbildung 1: Rekursiv verschachtelte Archivdateien, mit Diffoscope verglichen.

Überraschenderweise kam Diffoscope bei unseren Tests nicht damit klar, wenn das ZIP-Archiv ein mit XZ komprimiertes TAR-Archiv enthielt oder umgekehrt ein ZIP-Archiv in einem XZ-komprimierten Tarball lag. In diesen Fällen war das Tool nicht in der Lage, rekursiv in die enthaltenen Archive hinabzusteigen.

Da es sich bei Softwarepaketen meist nur um verschachtelte Archivdateien handelt, kommt Diffoscope auch mit ihnen zurecht. DEB-Pakete nutzen beispielsweise als äußere Hülle ein AR-Archiv, in dem zwei mittlerweile typischerweise mit unterschiedlichen Algorithmen (GZIP und XZ) komprimierte Tarballs liegen. Abbildung 2 zeigt den Vergleich zweier paketierter Versionen der Fp-utils.

Abbildung 2: Zwei Debian-Pakete verschiedener Softwareversionen im direkten Vergleich.

Abbildung 2: Zwei Debian-Pakete verschiedener Softwareversionen im direkten Vergleich.

Daneben beherrscht Diffoscope auch eine farbige Ausgabe im Webbrowser, etwa im HTML-Format (Abbildung 3). Mit dem Parameter --html Output.html benennen Sie die Ausgabedatei. Entspricht der mitgelieferte Stil nicht Ihren Ansprüchen, passen Sie ihn über den Schalter --css Style.css mit einem individuellen Stylesheet an.

Abbildung 3: Diffoscope erm&ouml;glicht auch eine farbige Ausgabe im Webbrowser.

Abbildung 3: Diffoscope ermöglicht auch eine farbige Ausgabe im Webbrowser.

Ein Nachteil von Diffoscope besteht darin, dass es je nach zu vergleichenden Dateiformaten oder Archivinhalten sehr viele (optionale) Abhängigkeiten braucht. Deswegen gibt es in Debian und Ubuntu mittlerweile sogar drei Varianten von Diffoscope: Das Paket diffoscope-minimal spielt nur die wichtigsten Abhängigkeiten ein, diffoscope installiert über seine Dependencies alle theoretisch möglichen Tools zum Berechnen menschenlesbarer Darstellungen der Unterschiede.

Das Debian- oder Pip-Paket trydiffoscope empfiehlt sich hingegen zum Ausprobieren der Funktion von Diffoscope ohne die Installation der vielen Abhängigkeiten. Das kleine Python-Skript lädt die als Parameter übergebenen Dateien in einen Webservice der Diffoscope-Entwickler hoch und lässt den Vergleich auf einem Server des Projekts erstellen. Das Resultat lädt das Tool zur Ausgabe direkt in einen Webbrowser. Stattdessen können Sie aber auch zwei Dateien per Webbrowser direkt auf die Try-Diffoscope-Webseite [9] hochladen.

Fazit und Ausblick

Wer bisher nur Diff kannte, ist nun um einiges schlauer: Es gibt fast für jeden Anwendungsfall einen passenden Differ, außer für YAML – hier förderten unsere Recherchen nichts Passendes zutage. In Teil 3 dieser Artikelserie besprechen wir in der kommenden Ausgabe GRC, den Generic Colouriser [10], der fast alle Formen von Ausgaben maßgeschneidert einfärbt. (cla/jlu)

Die Autoren

Frank Hofmann arbeitet zumeist von unterwegs aus als Entwickler, Trainer und Autor. Der Linux-Sysadmin und Netzwerksicherheitsspezialist Axel Beckert ist bei den Informatikdiensten der ETH Zürich tätig. Beide Autoren haben ein Standardwerk rund um das Debian-Paketmanagement verfasst.

Infos

  1. Diff-Werkzeuge (Teil 1): Axel Beckert, Frank Hofmann, “Vive la différence!”, LU 11/2021, S. 44, https://www.linux-community.de/46767

  2. Zutils: https://www.nongnu.org/zutils/zutils.html

  3. Zipcmp: https://libzip.org/documentation/zipcmp.html

  4. Atool: https://www.nongnu.org/atool/

  5. Software-News: Uwe Vollbracht, “Angetestet”, LU 08/2008, S. 14, https://www.linux-community.de/16211

  6. Jsondiff: https://pypi.org/project/jsondiff

  7. Diffoscope: https://diffoscope.org/

  8. The Reproducible Builds Project: https://reproducible-builds.org

  9. Try Diffoscope: https://try.diffoscope.org

  10. Generic Colouriser: https://github.com/garabik/grc

  11. PDFs vergleichen: Frank Hofmann, “Spurensuche”, LU 07/2015, S. 70, https://www.linux-community.de/33881

  12. Diff-pdf: https://vslavik.github.io/diff-pdf

  13. Pdf-diff: https://github.com/JoshData/pdf-diff

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 12/2021 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben