В основному, вам потрібно - це можливість передати файл в дьоготь і "переплести" передню частину, як ви йдете.
У StackOverflow хтось запитав, як обрізати файл спереду , але, здається, це неможливо. Ви все ще можете заповнити початок файлу нулями особливим чином, щоб файл став розрідженим файлом , але я не знаю, як це зробити. Однак ми можемо скоротити кінець файлу. Але дьогтю потрібно читати архів вперед, а не назад.
Рішення 1
Рівень непрямості вирішує кожну проблему. Спочатку переверніть файл на місці, а потім прочитайте його назад (що призведе до зчитування оригінального файлу вперед) і обрізайте кінець поверненого файлу по ходу.
Вам потрібно буде написати програму (c, python, що завгодно) для обміну початком і кінцем файлу, chunk by chunk, а потім передати ці фрагменти для tar, одночасно обрізаючи фрагмент файлу. Це основа для рішення 2, яке, можливо, є більш простим у виконанні.
Рішення 2
Інший метод - розділити файл на невеликі шматки на місці , а потім видалити ці фрагменти, коли ми їх витягуємо. У наведеному нижче коді розмір відрізка становить один мегабайт, коригуйте залежно від ваших потреб. Більший швидше, але займе більше проміжного простору при розщепленні та під час видобутку.
Розділити файл 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
Завантажте ці файли в tar (зауважте, нам потрібна змінна chunkprefix у другому терміналі):
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.
Оскільки ми використовуємо іменовану трубу ( mkfifo fifo
), вам не доведеться трубопроводити всі шматки відразу. Це може бути корисно, якщо ви дійсно обмежені в космосі. Ви можете виконати наступні дії:
- Перемістіть, скажіть, останні шматки 10 Гбіт на інший диск,
- Почніть видобуток із шматок, які у вас ще є,
- По закінченні
while [ -e … ]; do cat "$chunk…; done
циклу (другий термінал):
- НЕ зупиняйте
tar
команду, НЕ виймайте fifo (перший термінал), але ви можете запустити sync
, про всяк випадок,
- Перемістіть кілька витягнутих файлів, які, на вашу думку, завершені (tar не затримується в очікуванні, коли дані закінчать витяг цих файлів) на інший диск,
- Перемістіть інші шматки назад,
- Відновіть видобуток шляхом
while [ -e … ]; do cat "$chunk…; done
повторного запуску рядків.
Звичайно, це все від високого рівня , ви хочете спочатку перевірити, що в архіві фіктивних файлів все гаразд, тому що якщо ви помилитесь, то прощайтесь з даними .
Ви ніколи не дізнаєтесь, чи перший термінал ( tar
) фактично закінчив обробку вмісту файлу, тому якщо ви віддаєте перевагу, можете запустити це замість цього, але у вас не буде можливості безперебійно обмінюватися фрагментами з іншим диском:
chunkprefix="chunk_"
currentchunk=0
while [ -e "$chunkprefix$currentchunk" ]; do
cat "$chunkprefix$currentchunk" && rm -f "$chunkprefix$currentchunk"
currentchunk=$((currentchunk+1))
done | tar -xf -
Відмова від відповідальності
Зверніть увагу, що для роботи цього оболонка, хвіст і усікання повинні правильно обробляти 64-бітні цілі числа (для цього вам не потрібен 64-бітний комп'ютер, ані операційна система). Моє, але якщо запустити вищезазначений скрипт у системі без цих вимог, ви втратите всі дані в archive.tar .
І в будь-якому випадку щось інше, ніж це піде не так, ви все одно втратите всі дані в archive.tar, тому переконайтеся, що у вас є резервна копія даних.