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…; done
Schleife beendet ist (zweites Terminal):
- Stoppen Sie den
tar
Befehl NICHT, entfernen Sie NICHT das FIFO (erstes Terminal), aber Sie können es sync
fü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…; done
Zeilen 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.