RSYNC nie usuwa katalogów źródłowych

27

Korzystam z rsync do niezbędnego pobierania plików z serwera, a następnie usuwam pliki z serwera, gdy już je mam lokalnie. Pełne polecenie, które uruchamiam, znajduje się poniżej.

Powoduje to usunięcie plików na serwerze źródłowym, jednak nadal pozostają puste katalogi. Nie otrzymuję żadnych wiadomości ani błędów. Wszystkie dane wyjściowe są normalne. Być może jest to zamierzona funkcjonalność.

Jak mogę nakazać rsync wyczyścić wszystko, w tym katalogi?

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

Wersja jest 3.0.9 na obu końcach.

Sajan Parikh
źródło
Powiązane: unix.stackexchange.com/questions/78375/… | serverfault.com/questions/384110
Ciro Santilli 23 改造 中心 法轮功 六四 事件

Odpowiedzi:

13

Zachowanie --remove-source-files, które obserwujesz, jest dokładnie takie, jak określone przez man rsync:

--remove-source-files

   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.

Nie ma konkretnego polecenia do usunięcia katalogów, ponieważ te dwie dyskusje w StackExchange i ServerFault wyraźnie pokazują. Rozwiązanie sugeruje wydanie dwóch osobnych poleceń:

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

Ostatni fragment polecenia sugerowany w tych dwóch postach,

 rmdir source/

który jest potrzebny do usunięcia (teraz opróżnionego) katalogu źródłowego, ma ten formularz w tych postach, ponieważ OP i odpowiedzi używają rsync do przenoszenia dużych ilości plików na tym samym komputerze. W twoim przypadku będziesz musiał to zrobić ręcznie.

MariusMatutiae
źródło
5
rsync --deleteSugestia jest niebezpieczne, ponieważ ignoruje możliwość, że rsync nie została zakończona, czy istnieją nowe pliki u źródła. Metoda @ slhck findponiżej jest znacznie bezpieczniejsza.
Sai,
29

Strona podręcznika mówi nawet:

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

Jeśli chcesz usunąć puste katalogi ze źródła, jeśli nadal pozostały pliki, wykonaj:

find . -depth -type d -empty -delete

Ale w przypadku pustego katalogu głównego rm -rf <directory>wystarczy oczywiście wola.

slhck
źródło
5
tak, to jedyne rozwiązanie. to trochę głupie brakująca funkcja rsync ... rsync wie, kiedy jest przetwarzany ostatni plik w katalogu ... łatwo jest usunąć katalog również, jeśli jest pusty.
Erik Aronesty
4
Uwaga: wydanie „rm -rf” jest podatne na warunki wyścigowe i odradzam.
Raúl Salinas-Monteagudo
Wariant, który nie usuwa pustego katalogu najwyższego poziomu:find some_dir -depth -type d -empty -not -path some_dir -delete
Cameron Tacklind
5

Użycie „ rm -rf ” ma nieodłączny warunek wyścigu, możesz mianowicie usunąć pliki, które zostały właśnie utworzone między wywołaniami rsync i rm .

Wolę używać:

rsync --remove-source-files -a serwer: przychodzące / przychodzące / &&

serwer ssh znajduje przychodzące -type d -delete

NIE spowoduje to usunięcia katalogów, jeśli nie są puste.

Raúl Salinas-Monteagudo
źródło
2
rm -rfRównież usunąć pliki, które nie zostały przeniesione z jakiegoś powodu.
Kristian
1
W tej odpowiedzi nie ma -depthopcji, która nakazuje findprzetwarzanie we właściwej kolejności. W wyniku tego braku katalogi zawierające tylko puste katalogi (ewentualnie rekurencyjnie) nie zostaną usunięte. Wariant @slhck ma rację.
Stéphane Gourichon
1

-m, --prune-empty-dirs przycinaj puste łańcuchy katalogów z listy plików

--force wymusić usunięcie katalogów, nawet jeśli nie są puste

MarcoP
źródło
1
To po prostu uniemożliwia rsync kopiowanie pustych katalogów. Nie usuwa pustych katalogów.
Navin
1

Usuń pliki źródłowe, a następnie usuń katalogi, aby zachować bezpieczeństwo.

# 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;

Więcej na temat GNU Parallel

Daniel Andrei Mincă
źródło