Zasadniczo potrzebna jest możliwość potokowania pliku do pliku tar i „obcinania” frontu podczas pracy.
Na StackOverflow ktoś zapytał, jak obciąć plik z przodu , ale wydaje się, że nie jest to możliwe. Nadal możesz wypełnić początek pliku zerami w specjalny sposób, aby plik stał się plikiem rzadkim , ale nie wiem, jak to zrobić. Możemy jednak obciąć koniec pliku. Ale tar musi czytać archiwum do przodu, a nie do tyłu.
Rozwiązanie 1
Poziom pośredni rozwiązuje każdy problem. Najpierw odwróć plik na miejscu, a następnie przeczytaj go wstecz (co spowoduje odczytanie oryginalnego pliku do przodu) i obcinaj koniec odwróconego pliku podczas pracy.
Musisz napisać program (c, python, cokolwiek), aby wymienić początek i koniec pliku, fragment po kawałku, a następnie potokować te fragmenty do tar, jednocześnie obcinając plik po kawałku. Jest to podstawa rozwiązania 2, które może być łatwiejsze do wdrożenia.
Rozwiązanie 2
Inną metodą jest podzielenie pliku na małe fragmenty w miejscu , a następnie usunięcie tych fragmentów podczas ich wyodrębniania. Poniższy kod ma wielkość jednego megabajta, dostosuj go w zależności od potrzeb. Większy jest szybszy, ale zajmie więcej pośredniej przestrzeni podczas podziału i podczas ekstrakcji.
Podziel plik 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
Prześlij te pliki do tar (uwaga: potrzebujemy zmiennej chunkprefix w drugim terminalu):
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.
Ponieważ używamy nazwanego potoku ( mkfifo fifo
), nie musisz potokować wszystkich porcji jednocześnie. Może to być przydatne, jeśli masz mało miejsca. Możesz wykonać następujące kroki:
- Przenieś, powiedzmy, ostatnie 10 Gb na inny dysk,
- Rozpocznij ekstrakcję kawałkami, które wciąż masz,
- Po zakończeniu
while [ -e … ]; do cat "$chunk…; done
pętli (drugi terminal):
- NIE zatrzymuj
tar
polecenia, NIE usuwaj fifo (pierwszego terminala), ale możesz uruchomić sync
, na wszelki wypadek,
- Przenieś niektóre wyodrębnione pliki, o których wiesz, że są kompletne (tar nie jest zablokowany, czekając, aż dane zakończą rozpakowywanie tych plików) na inny dysk
- Przenieś pozostałe fragmenty do tyłu,
- Wznów ekstrakcję
while [ -e … ]; do cat "$chunk…; done
, ponownie uruchamiając linie.
Oczywiście to wszystko haute voltige , najpierw sprawdź, czy wszystko w porządku w archiwum fikcyjnym , bo jeśli popełnisz błąd, to pożegnaj się z danymi .
Nigdy nie dowiesz się, czy pierwszy terminal ( tar
) faktycznie zakończył przetwarzanie zawartości fifo, więc jeśli wolisz, możesz uruchomić to zamiast tego, ale nie będziesz mieć możliwości płynnej wymiany fragmentów na inny dysk:
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
currentchunk=$((currentchunk+1))
done | tar -xf -
Zrzeczenie się
Pamiętaj, że aby wszystko to działało, twoja powłoka, ogon i obcięcie muszą poprawnie obsługiwać 64-bitowe liczby całkowite (nie potrzebujesz do tego 64-bitowego komputera ani systemu operacyjnego). Mój tak, ale jeśli uruchomisz powyższy skrypt w systemie bez tych wymagań, stracisz wszystkie dane w pliku archive.tar .
W każdym razie coś innego nie działa, i tak stracisz wszystkie dane w pliku archive.tar, więc upewnij się, że masz kopię zapasową danych.