An Ort und Stelle Teerarchiv extrahieren


14

Ich habe hier ein kleines Dilemma ...

Ich musste Dateien im Wert von etwa 70 GB von einem meiner Server auf den anderen verschieben, daher entschied ich, dass das Teern und Senden des Archivs der schnellste Weg ist.

Der empfangende Server verfügt jedoch nur noch über 5 GB Speicherplatz nach dem Empfang des Tar-Archivs.

Gibt es eine Möglichkeit, den Teer "an Ort und Stelle" zu extrahieren? Ich muss das Archiv nicht behalten, nachdem es extrahiert wurde, also habe ich mich gefragt, ob dies möglich ist.

Bearbeiten: Es sollte beachtet werden, dass das Archiv bereits gesendet wurde, und ich möchte vermeiden, dass es erneut über eine andere Methode gesendet wird.

Antworten:


11
% tar czf - stuff_to_backup | ssh backupmachine tar xvzf -

Dies bedeutet:

  • tar und komprimiere 'stuff_to_backup' auf stdout
  • Melden Sie sich über ssh bei 'backupmachine' an
  • Führen Sie 'tar' auf der 'backupmachine' aus und entpacken Sie die von stdin eingehenden Daten

Ich persönlich würde 'rsync over ssh' verwenden, um das Zeug zu übertragen, weil Sie das Zeug weiter übertragen können, wenn die Verbindung unterbrochen wird:

% rsync -ar --progress -e 'ssh' 'stuff_to_backup' user@backupmachine:/backup/

Dadurch wird alles von 'stuff_to_backup' in den Ordner 'backup' auf der 'backupmachine' übertragen. Wenn die Verbindung unterbrochen wird, wiederholen Sie einfach den Befehl. Wenn sich einige Dateien in 'stuff_to_backup' ändern, wiederholen Sie das Zeug, nur der Unterschied wird übertragen.


Siehe meine bearbeitete Frage
anonymer Feigling

@Charlie Somerville: Ja, Sie haben den wichtigen Teil überhaupt weggelassen. :)
Akira

6

Wenn der andere Computer ssh hat, würde ich Ihnen rsync als eine andere Alternative empfehlen, die keine tar-Datei verwendet:

rsync -avPz /some/dir/ user@machine:/some/other/dir/

Und sei vorsichtig mit der Führung /

Update bearbeiten

Nun, ich sehe, dass dies jetzt eine großartige Lösung ist, wenn Sie es nicht löschen und mit rsync neu beginnen können. Ich würde wahrscheinlich einen selektiven Auszug versuchen und aus dem Teer löschen.

selektiver Extrakt:

$ tar xvf googlecl-0.9.7.tar googlecl-0.9.7/README.txt
googlecl-0.9.7/README.txt

selektives Löschen:

$ tar --delete --file=googlecl-0.9.7.tar googlecl-0.9.7/README.txt

Es scheint jedoch, dass Sie viel Zeit damit verbringen werden, ein Skript dafür zu programmieren ...


Siehe meine bearbeitete Frage
anonymer Feigling

Siehe meine bearbeitete Antwort ... viel Glück: - /
YuppieNetworking

Danke für die Bearbeitung. Die Dateien sind tatsächlich mit Zahlen benannt, sodass eine schnelle for-Schleife in bash möglicherweise den Trick macht.
Anonymer Feigling

1
@Charlie Somerville: Möglicherweise müssen Sie mit den am Ende des Teers gespeicherten Dateien beginnen, andernfalls können Sie mit der Erstellung eines neuen Archivs durch tar enden. Löschen Sie daher zuerst die Dateien am Ende des Teers.
Akira

5

Grundsätzlich benötigen Sie die Möglichkeit, die Datei in Teer zu leiten und die Vorderseite zu "hacken", während Sie gehen.

In StackOverflow hat jemand gefragt, wie eine Datei vorne abgeschnitten werden soll , aber es scheint, dass dies nicht möglich ist. Sie könnten den Anfang der Datei immer noch auf besondere Weise mit Nullen füllen, damit die Datei zu einer spärlichen Datei wird , aber ich weiß nicht, wie das geht. Wir können jedoch das Ende der Datei abschneiden. Aber tar muss das Archiv vorwärts und nicht rückwärts lesen.

Lösung 1

Eine Indirektionsebene löst jedes Problem. Kehren Sie die Datei zuerst an Ort und Stelle um, lesen Sie sie dann rückwärts (was dazu führt, dass die Originaldatei vorwärts gelesen wird) und schneiden Sie das Ende der umgekehrten Datei ab, während Sie fortfahren.

Sie müssen ein Programm (c, Python, was auch immer) schreiben, um den Anfang und das Ende der Datei Stück für Stück auszutauschen und diese Stücke dann an tar weiterzuleiten, während Sie die Datei Stück für Stück abschneiden. Dies ist die Basis für Lösung 2, die möglicherweise einfacher zu implementieren ist.

Lösung 2

Eine andere Methode besteht darin , die Datei an Ort und Stelle in kleine Blöcke aufzuteilen und diese Blöcke beim Extrahieren zu löschen. Der folgende Code hat eine Blockgröße von einem Megabyte und kann je nach Ihren Anforderungen angepasst werden. Größer ist schneller, benötigt jedoch beim Teilen und beim Extrahieren mehr Zwischenraum.

Teilen Sie die Datei archive.tar:

archive="archive.tar"
chunkprefix="chunk_"
# 1-Mb chunks :
chunksize=1048576

totalsize=$(wc -c "$archive" | cut -d ' ' -f 1)
currentchunk=$(((totalsize-1)/chunksize))
while [ $currentchunk -ge 0 ]; do
    # Print current chunk number, so we know it is still running.
    echo -n "$currentchunk "
    offset=$((currentchunk*chunksize))
    # Copy end of $archive to new file
    tail -c +$((offset+1)) "$archive" > "$chunkprefix$currentchunk"
    # Chop end of $archive
    truncate -s $offset "$archive"
    currentchunk=$((currentchunk-1))
done

Pipe diese Dateien in tar (beachten Sie, dass wir die Variable chunkprefix im zweiten Terminal benötigen):

mkfifo fifo
# In one terminal :
(while true; do cat fifo; done) | tar -xf -
# In another terminal :
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
    cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
    currentchunk=$((currentchunk+1))
done > fifo
# When second terminal has finished :
# flush caches to disk :
sync
# wait 5 minutes so we're sure tar has consumed everything from the fifo.
sleep 300
rm fifo
# And kill (ctrl-C) the tar command in the other terminal.

Da wir eine Named Pipe ( mkfifo fifo) verwenden, müssen Sie nicht alle Chunks gleichzeitig leiten. Dies kann nützlich sein, wenn Sie sehr wenig Platz haben. Sie können die folgenden Schritte ausführen:

  • Verschieben Sie die letzten 10-GB-Blöcke auf eine andere Festplatte.
  • Starten Sie die Extraktion mit den noch vorhandenen Stücken.
  • Wenn die while [ -e … ]; do cat "$chunk…; doneSchleife beendet ist (zweites Terminal):
  • Stoppen Sie den tarBefehl NICHT, entfernen Sie NICHT das FIFO (erstes Terminal), aber Sie können es syncfür alle Fälle ausführen .
  • Verschieben Sie einige extrahierte Dateien, von denen Sie wissen, dass sie vollständig sind (tar ist nicht blockiert, bis die Daten das Extrahieren dieser Dateien abgeschlossen haben), auf eine andere Festplatte.
  • Bewegen Sie die restlichen Stücke zurück,
  • Setzen Sie die Extraktion fort, indem Sie die while [ -e … ]; do cat "$chunk…; doneZeilen erneut ausführen .

Natürlich ist das alles Haute Voltige . Sie sollten zuerst überprüfen, ob in einem Dummy-Archiv alles in Ordnung ist. Wenn Sie einen Fehler machen, verabschieden Sie sich von den Daten .

Sie werden nie erfahren, ob das erste Terminal ( tar) den Inhalt des FIFO tatsächlich verarbeitet hat. Wenn Sie es vorziehen, können Sie dies stattdessen ausführen, aber Sie haben nicht die Möglichkeit, Chunks nahtlos mit einer anderen Festplatte auszutauschen:

chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
    cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
    currentchunk=$((currentchunk+1))
done | tar -xf -

Haftungsausschluss

Beachten Sie, dass Shell, Tail und Truncate 64-Bit-Ganzzahlen korrekt verarbeiten müssen, damit dies funktioniert. Dazu benötigen Sie weder einen 64-Bit-Computer noch ein Betriebssystem. Meins tut es, aber wenn Sie das obige Skript auf einem System ohne diese Anforderungen ausführen, verlieren Sie alle Daten in archive.tar .

Und in jedem Fall geht etwas anderes schief, Sie verlieren trotzdem alle Daten in archive.tar. Stellen Sie also sicher, dass Sie eine Sicherungskopie Ihrer Daten haben.


0

Wenn Sie Objektdateien verschieben möchten, entfernen Sie diese. Dies spart viel Platz.

$ strip `find . -name "*.bin"`
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.