Перемістити файли та видалити каталоги за допомогою rsync?


17

Нещодавно мені потрібно було видалити велику кількість файлів (понад 1 мільйон), і я прочитав це:

rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

Це був один з найбільш оптимізованих способів зробити це, і я можу поручити, що це швидше, ніж rm -rf.

Я не фахівець з цього питання, але, з мого розуміння, причина виконання rsync має щось робити так, як вона перераховує файли (я думаю, LIFO замість FIFO). Тепер проблема полягає в тому, що мені також потрібно ефективно перемістити велику кількість файлів. Трохи пошукавши, я виявив таке:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination

Хоча це видаляє всі переміщені файли в ~/source, каталоги залишаються там. Оскільки у мене є структура каталогів «круглобітка», кількість files/directoriesдуже близька до 1, тому я змушений запустити першу команду ще раз, щоб повністю позбутися каталогу:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination && \
rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

Прямий mvзакінчується практично миттєво, але в моєму ~/destinationкаталозі є файли, які слід зберігати, тому mvце не варіант. Я знайшов параметри --prune-empty-dirsі --forcersync, але, здається, не працює так, як я очікував:

--force                 force deletion of directories even if not empty
--prune-empty-dirs      prune empty directory chains from the file-list
--remove-source-files   sender removes synchronized files (non-dirs)

Чи є спосіб імітувати рух за допомогою rsync за один раз?


2
Якщо ви не отримаєте відповіді тут, спробуйте опублікувати в списку rsync. Вони дуже корисні. list.samba.org/mailman/listinfo/rsync
Джо

Відповіді:


7

Я знайшов цю тему в stackoverflow під назвою: Видалення папок з rsync “переміщення”? , що задає по суті те саме питання. Один з відповідей пропонував виконувати rsyncкоманди 2, оскільки, здається, немає жодної команди, яка може виконати переміщення / видалення файлів та вихідних каталогів.

$ rsync -av --ignore-existing --remove-source-files source/ destination/ && \
  rsync -av --delete `mktemp -d`/ source/ && rmdir source/

Можна також зробити це за допомогою цієї команди:

$ rsync -axvvES --remove-source-files source_directory /destination/ && \
  rm -rf source_directory

Не ідеально, але робить роботу.


Так, саме я відповів на це питання (і те саме "рішення" є і в цьому питанні). = P
Алікс Аксель

@AlixAxel - Ха, вибач, що я навіть не помітив, що ти відповів на це. Що ж, добре. Чи потрібно потім видалити цю відповідь?
slm

3
Використовувати rsyncдля обрізки каталогів це не правильно, і завжди є небезпека rm -rf. Я б рекомендував 2 - й крок , щоб бути:find source/ -d -type d -exec rmdir {} \;
ідіотський

2
Я просто змушений додавати, ніколи не використовувати -deleteі --remove-source-filesв одній команді rsync (наведені вище приклади чудово, це дотично). Якщо ви перервете потім повторно виконаєте те, що я описую, ви втратите передані файли. Що я робив раніше :(
Шрідхар Сарнобат

Прибираючи find, я віддаю перевагу саме такому: find source/ -type d -empty -delete це дає мені дивне почуття заспокоєння, що воно не просто заграє все.
greyfade

10

Від коментаря zany до відповіді slm ( Перемістити файли та видалити каталоги за допомогою rsync? ) Я б рекомендував ці 2 команди як відповідь:

rsync -av --ignore-existing --remove-source-files source/ destination/ && \
find source/ -depth -type d  -empty -exec rmdir "{}" \;

Перевага полягає в тому, що, як сказав Джані, все ж є небезпека використання rm -rf, якщо ви не зрозумієте це правильно або для початківців.

Я додав 2 варіанти, -depth та -empty, і хоча я не впевнений, чи справді це потрібно, він робить другу команду більш портативною для інших ситуацій і навіть більш безпечною (вона все одно робить правильно, якщо деякі каталоги не порожні і починає видалення з найглибшої точки дерева дерев)


чому б не просто -deleteзамість -exec rmdir {} \;?
літаючі вівці

@flying_sheep см коментар user7000 у відповідь ігрова сіма: коли Rsync IST перервала ви можете втратити файли
міт

Коли rsync переривається, знахідка ніколи не починається чи ні? Таким чином, видалення в секунді rsync не повинно бути проблемою. Але -delete також видаляє файли, замість цього rmdir ніколи не видаляє файли, а лише каталоги. Обидва (-delete та rmdir) перевіряють каталоги, якщо вони порожні перед видаленням.
benba

Крім того, на сторінках man говориться, що ви повинні використовувати -execdir замість -exec ...
benba

2

Це робить роботу в один крок. Зверніть увагу на проміжок / проріз / як на вихідний, так і на цільовий контури.

rsync \
    -ruval \
    --ignore-existing \
    --remove-source-files \
    --prune-empty-dirs \ 
    /source/path/ /target/path/

Я повторюю застереження від user7000 не використовувати --deleteі --remove-source-filesразом в одному дзвінку rsync. Якщо операція завершиться невдало або перервана і повторився той самий дзвінок, ви втратите дані. Якщо в якийсь - або сумніви, використовуйте --dry-runопцію , щоб побачити , що буде зроблено.


-ruvalздається зайвим. -aеквівалентний -rlptgoD, що включає в себе і те, -rі -l.
greyfade
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.