RSYNC не видаляє вихідні каталоги


27

Я використовую rsync для отримання необхідних файлів із сервера, а потім видаляю файли з сервера, як тільки я їх матиму локально. Повна команда, яку я виконую, наведена нижче.

Це успішно видаляє файли на вихідному сервері, однак порожні каталоги все ще залишаються. Я не отримую жодних повідомлень чи помилок. Весь вихід нормальний. Можливо, це призначений функціонал.

Як я можу сказати rsync прибирати все, включаючи каталоги?

rsync --progress -vrzh --remove-source-files

Версія 3.0.9 на обох кінцях.


Відповіді:


13

Поведінка, --remove-source-filesяку ви спостерігаєте, саме така, що визначена man rsync:

--remove-source-файли

   This tells rsync to remove from the sending side the files (meaning non-directories) that are a part of the transfer and have been successfully duplicated on the receiving side.

Немає конкретної команди для видалення каталогів, як це чітко видно з цих двох обговорень у StackExchange та ServerFault . Запропоновано рішення: випустити дві окремі команди:

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

Останній фрагмент команди, запропонований у цих двох постах,

 rmdir source/

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


5
rsync --deleteПропозиція небезпечно, тому що вона ігнорує можливість того, що Rsync не був завершений, або з'явилися нові файли в джерелі. Метод @ slhck findнижче є набагато безпечнішим.
Сай

29

На сторінці написано навіть:

--remove-source-files   sender removes synchronized files (non-dirs)

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

find . -depth -type d -empty -delete

Але для порожнього кореневого каталогу, rm -rf <directory>звичайно, достатньо заповіту.


5
так, це єдине рішення. це якась нерозумна відсутність функції rsync ... rsync знає, коли обробляється останній файл у каталозі ... досить просто видалити dir, якщо він порожній.
Ерік Аронесті

4
Будьте уважні, що видача "rm -rf" є схильною до перегонів, і я перешкоджаю цьому.
Рауль Салінас-Монтеагудо

Варіант, який не стирає порожній каталог верхнього рівня:find some_dir -depth -type d -empty -not -path some_dir -delete
Cameron Tacklind,

5

Використання " rm -rf " має притаманну умові гонки, ви можете видалити файли, що були тільки що створені між викликами rsync та rm .

Я вважаю за краще використовувати:

rsync - вилучити-вихідні файли - сервер: вхідні / вхідні / &&

ssh-сервер знайти вхідний тип d -delete

Це НЕ буде видаляти каталоги, якщо вони не порожні.


2
Також rm -rfбуде видалено файли, які з певних причин не були передані.
Крістіан

1
У цій відповіді відсутня -depthопція, яка доручає findобробляти в правильному порядку. У результаті цього пропуску каталоги, які містять лише порожні каталоги (можливо, рекурсивно), не будуть видалені. Версія @slhck має право.
Стефан Гурішон

1

-m, --prune-empty-dirs обріжте порожні ланцюжки каталогів із списку файлів

--force примусове видалення брусів, навіть якщо вони не порожні


1
Це просто заважає rsync копіювати порожні гноми. Він не видаляє порожні пані.
Навін

1

Видаліть вихідні файли, а потім видаліть каталоги, щоб бути безпечними.

# given this scenario where you generate folders 2014-01-01 etc.. that have an archive myfile.tar.gz
pushd $(mktemp -d)
mkdir 201{4..6}-{01..12}-{01..31}
for i in $(ls); do; touch $i/myfile.tar.gz;done;
# find and rsync on 10 CPU threads directories that match ./2015-*
find /tmp/tmp.yjDyF1jN70/src -type d -name '2015-*' | \
parallel \
--jobs 10 \
--progress \
--eta \
--round-robin \
rsync \
--hard-links \
--archive --verbose --protect-args \
--remove-source-files \
{} /tmp/tmp.yjDyF1jN70/dest
# now safely remove empty directories only
for i in $(ls /tmp/tmp.yjDyF1jN70/src); do; rmdir /tmp/tmp.yjDyF1jN70/src/$i; done;

Детальніше про GNU Paralel

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