Mehrere TAR-Dateien in einem Befehl verketten

Mehrere TAR-Dateien in einem Befehl verketten

Ich erhalte täglich zwischen 4 und 100 sehr große Tar-Archivdateien (~20 GB). Ich habe sie in der Vergangenheit verkettet, indem ich alle Archive, die ich im Dateisystem sehe, durchgegangen bin und so etwas gemacht habe

/bin/tar -concatenate --file=allTars.tar receivedTar.tar

Das Problem dabei ist jedoch, dass, wenn ich immer mehr Tar-Dateien verkette, es bis zum Ende lesen muss, allTars.tarum erneut mit der Verkettung zu beginnen. Manchmal dauert es über 20 Minuten, bis mit dem Hinzufügen einer weiteren Tar-Datei begonnen wird. Es ist einfach zu langsam und ich verpasse eine vereinbarte Lieferzeit der vollständigen allTars.tar.

Ich habe auch versucht, meinem Tar-Befehl eine Dateiliste wie folgt zu übergeben:

/bin/tar --concatenate --file=alltars.tar receiverTar1.tar receivedTar2.tar receivedTar3.tar...etc

Dies führte zu sehr merkwürdigen Ergebnissen. allTars.tarEs hatte die erwartete Größe (also ungefähr die Summe der receivedTar.tarGrößen aller Dateien), aber es schien, als würden beim allTars.tarEntpacken Dateien überschrieben.

Gibt es eine Möglichkeit, alle diese Tar-Dateien in einem Befehl zu verketten, sodass nicht jedes Mal bis zum Ende des zu verkettenden Archivs gelesen werden muss?UndHaben Sie diese richtig und mit allen Dateien/Daten entpackt?

Antwort1

Dies hilft Ihnen möglicherweise nicht weiter, aber wenn Sie die Option beim Extrahieren aus dem endgültigen Archiv verwenden möchten -i, können Sie catdie Tars einfach zusammenfassen. Eine Tar-Datei endet mit einem Header voller Nullen und weiteren Null-Paddings bis zum Ende des Datensatzes. Mit --concatenateTar müssen Sie alle Header durchgehen, um die genaue Position des endgültigen Headers zu finden, um dort mit dem Überschreiben zu beginnen.

Wenn Sie nur catdie Tars verwenden, haben Sie nur zusätzliche Nullen zwischen den Headern. Die -iOption weist Tar an, diese Nullen zwischen den Headern zu ignorieren. Sie können also

cat  receiverTar1.tar receivedTar2.tar ... >>alltars.tar
tar -itvf alltars.tar

Außerdem tar --concatenatesollte Ihr Beispiel funktionieren. Wenn Sie jedoch dieselbe benannte Datei in mehreren Tar-Archiven haben, werden Sie diese Datei mehrmals neu schreiben, wenn Sie alles aus dem resultierenden Tar extrahieren.

Antwort2

Diese Frage ist schon ziemlich alt, aber ich wünschte, ich hätte die folgenden Informationen früher leichter finden können. Wenn also noch jemand darüber stolpert, viel Spaß damit:

Was Jeff oben beschreibt, ist ein bekannter Fehler in Gnu Tar (gemeldet im August 2008). Nur beim ersten Archiv (dem nach der -fOption) wird der EOF-Marker entfernt. Wenn Sie versuchen, mehr als zwei Archive zu verketten, werden die letzten Archive hinter Dateiende-Markern „versteckt“.

Es handelt sich um einen Fehler in Tar. Es verkettet ganze Archive, einschließlich nachfolgender Nullblöcke, sodass das Lesen des resultierenden Archivs standardmäßig nach der ersten Verkettung stoppt.

Quelle:https://lists.gnu.org/archive/html/bug-tar/2008-08/msg00002.html (und folgende Nachrichten)

Angesichts des Alters des Fehlers frage ich mich, ob er jemals behoben wird. Ich bezweifle, dass eine kritische Masse betroffen ist.

Die beste Möglichkeit, diesen Fehler zu umgehen, besteht möglicherweise darin, diese -iOption zumindest für .tar-Dateien auf Ihrem Dateisystem zu verwenden.

Wie Jeff anmerkt, tar --concatenatekann es lange dauern, bis das EOF erreicht ist und das nächste Archiv angehängt wird. Wenn Sie also mit einem „defekten“ Archiv festsitzen, das die tar -iOption zum Entpacken benötigt, schlage ich Folgendes vor:

Anstatt tar --concatenate -f archive1.tar archive2.tar archive3.tar Sie werden wahrscheinlich besser dran sein, zu laufen cat archive2.tar archive3.tar >> archive1.taroder Pipe to dd, wenn Sie auf ein Bandgerät schreiben möchten. Beachten Sie auch, dass dieskönntezu unerwartetem Verhalten führen, wenn die Bänder nicht auf Null gesetzt werden, bevor neue Daten darauf (überschrieben) werden. Aus diesem Grund werde ich in meiner Anwendung verschachtelte Tars verwenden, wie in den Kommentaren unter der Frage vorgeschlagen.

Der obige Vorschlag basiert auf dem folgenden sehr kleinen Beispiel-Benchmark:

time tar --concatenate -vf buffer.100025.tar buffer.100026.tar
  real  65m33.524s
  user  0m7.324s
  sys   2m50.399s

time cat buffer.100027.tar >> buffer.100028.tar
  real  46m34.101s
  user  0m0.853s
  sys   1m46.133s

Die buffer.*.tar-Dateien sind alle 100 GB groß, das System war bis auf die einzelnen Anrufe ziemlich im Leerlauf. Der Zeitunterschied ist so groß, dass ich persönlich diesen Benchmark trotz der kleinen Stichprobengröße für gültig halte, aber Sie können dies selbst beurteilen und es ist wahrscheinlich am besten, einen solchen Benchmark auf Ihrer eigenen Hardware auszuführen.

Antwort3

Wie Sie bereits gesagt haben, muss die Zielarchivdatei bis zum Ende gelesen werden, bevor das zweite Quellarchiv daran angehängt wird. GNU Tar verfügt über eine -nOption, die es anweist, davon auszugehen, dass eine Datei suchbar ist (denken Sie daran, dass Tar für Band- und Streamarchive entwickelt wurde, die nicht suchbar sind). GNU Tar erkennt standardmäßig automatisch, ob eine Datei suchbar ist. Viele Benutzer wie Sie können jedoch sicherstellen, dass Tar das Lesen des gesamten Inhalts jedes Datensatzes überspringt, indem sie die folgende -nOption hinzufügen:

tar -n --concatenate --file=target_file.tar  other_file.tar

Ich kann (zum Zeitpunkt des Schreibens) nicht überprüfen, welche Tar-Versionen (falls vorhanden) für diesen Befehl die erwartete Leistung erbringen. Wenn andere Benutzer diese Lösung beweisen können, hinterlassen Sie unten einen Kommentar und ich werde diese Antwort entsprechend aktualisieren.

Antwort4

Da die Verkettung I/O-intensiv ist, würde ich entweder 3 SSDs (1 TB) in einem RAID 0 empfehlen. Eine einzelne SSD auf SATA 3 bietet 500 MB/s beim Lesen und ähnliches beim Schreiben. Teuer, ja, aber schnell x3.

verwandte Informationen