RSYNC не удаляет исходные каталоги

27

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

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

Как я могу сказать rsync очистить все, включая каталоги?

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

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

Саджан Парих
источник
Связанный: unix.stackexchange.com/questions/78375/… | serverfault.com/questions/384110/…
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件

Ответы:

13

Поведение того, --remove-source-filesчто вы наблюдаете, точно соответствует man rsync:

--remove-исток-файлы

   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/

который необходим для удаления (теперь опустошенного) исходного каталога, имеет такую ​​форму в этих сообщениях, потому что OP и ответы используют rsync для перемещения большого количества файлов на одном компьютере. В вашем случае вам придется сделать это вручную.

MariusMatutiae
источник
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>конечно , будет достаточно.

slhck
источник
5
да, это единственное решение. это своего рода глупая отсутствующая функция rsync ... rsync знает, когда он обработал последний файл в каталоге ... достаточно просто удалить каталог, если он пуст.
Эрик Аронести
4
Остерегайтесь того, что выдача «rm -rf» является склонной к гонкам, и я не одобряю это.
Рауль Салинас-Монтеагудо
Вариант, который не стирает пустой каталог верхнего уровня:find some_dir -depth -type d -empty -not -path some_dir -delete
Кэмерон Таклинд
5

Использование « rm -rf » имеет неотъемлемое условие гонки, а именно вы можете удалить файлы, которые были только что созданы между вызовами rsync и rm .

Я предпочитаю использовать:

rsync --remove-source-files -a сервер: входящий / входящий / &&

SSH-сервер найти входящий -type d -delete

Это НЕ удалит каталоги, если они не пусты.

Рауль Салинас-Монтеагудо
источник
2
Также rm -rfбудут удалены файлы, которые не были перенесены по какой-либо причине.
Кристиан
1
Этот ответ пропускает -depthопцию, которая дает команду findобрабатывать в правильном порядке. В результате этой ошибки каталоги, которые содержат только пустые каталоги (возможно, рекурсивно), не будут удалены. Вариант от @slhck имеет это право.
Стефан Гурихон
1

-m, --prune-empty-dirs удалить пустые цепочки каталогов из списка файлов

--force принудительно удалить каталоги, даже если они не пусты

MarcoP
источник
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 Parallel

Даниэль Андрей Минкэ
источник