На місці архіву екстракту дьогтю


14

У мене тут невелика дилема ...

Мені потрібно було перемістити файли близько 70 Гб з одного з моїх серверів на інший, тому я вирішив, що швидке спрямування їх та відправлення архіву буде найшвидшим способом.

Однак серверу прийому залишається лише 5 ГБ місця після отримання архіву смоли.

Чи є якийсь спосіб я добути дьоготь «на місці»? Мені не потрібно зберігати архів після його вилучення, тому мені було цікаво, чи можна це зробити.

Редагувати: Слід зазначити, що архів вже надісланий, і я хотів би уникати повторного повторного використання іншим методом.

Відповіді:


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

це означає:

  • тар і стиснути 'stuff_to_backup' до stdout
  • увійдіть до 'backupmachine' через ssh
  • запустіть "смолу" на "резервній машині" та зніміть речі, що надходять із stdin

я особисто використовував би "rsync over ssh" для передачі матеріалів, оскільки ви можете продовжувати передачу матеріалів, якщо з'єднання розривається:

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

який перенесе все з 'stuff_to_backup' в папку 'backup' на 'backupmachine'. якщо з’єднання розривається, просто повторіть команду. якщо деякі файли в 'stuff_to_backup' змінюються, повторіть цей матеріал, передається лише різниця.


Дивіться моє відредаговане запитання
анонімний боягуз

@Charlie Somerville: так, ви залишили важливу частину в першу чергу. :)
akira

6

Якщо інша машина має ssh, я рекомендую вам rsync як іншу альтернативу, яка не використовує файл tar:

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

І будьте обережні з ведучими /

Редагувати оновлення

Ну, я бачу, як зараз це чудовий соління, якщо ви не в змозі його видалити і розпочати з rsync. Я, мабуть, спробував би вибірковий екстракт і видалити з дьогтю.

вибірковий екстракт:

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

вибіркове видалення:

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

Однак, схоже, що ви витратите багато часу на кодування сценарію для цього ...


Дивіться моє відредаговане запитання
анонімний боягуз

Дивіться мою відредаговану відповідь ... удачі: - /
YuppieNetworking

Дякуємо за редагування Файли насправді названі цифрами, так що швидкий цикл в bash може просто зробити свою справу.
анонімний боягуз

1
@Charlie Somerville: можливо, вам доведеться починати з файлів, що зберігаються в кінці tar, інакше ви можете закінчити створенням tar нового архівного файлу ... так що спочатку видаліть файли з кінця tar.
акіра

5

В основному, вам потрібно - це можливість передати файл в дьоготь і "переплести" передню частину, як ви йдете.

У 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, тому переконайтеся, що у вас є резервна копія даних.


0

Якщо у вас є об’єктні файли, які потрібно перемістити, спробуйте зняти їх. Це заощадить значну кількість місця.

$ strip `find . -name "*.bin"`
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.