rsync, usuń pliki po stronie odbiorczej, które zostały usunięte po stronie wysyłającej. (Ale nie usuwaj wszystkiego)

9

Chciałbym użyć rsync do ...

  • usuń pliki po stronie odbierającej, które zostały również usunięte po stronie wysyłającej
  • nie usuwaj innych plików, które znajdują się w katalogu rsynced po stronie odbierającej

Załóżmy na przykład, że mam katalog local-src:

PRZED: local-src lokalnie zawiera ...

a.txt
b.txt
c.txt

local-srcnazywany jest mój zdalny katalog, który chciałbym zsynchronizować z zawartością remote-src.

PRZED: remote-src zdalnie zawiera ...

a.txt
b.txt
c.txt
d.txt
README.md

Powiedzmy, że usuwam niektóre pliki w local-src:

PO USUNIĘCIU LOKALNYM: local-src lokalnie zawiera ...

c.txt

Jak mogę użyć rsync w taki sposób, aby pliki usunięte u źródła zostały również usunięte w miejscu docelowym, ale bez usuwania innych plików w miejscu docelowym. Na przykład chciałbym mieć następujące miejsca docelowe:

PO USUNIĘCIU LOKALNYM: remote-src zdalnie zawiera ...

c.txt
d.txt
README.md

Oznacza to, a.txti b.txtsą zdalnie usunięte, jak również, ale d.txti README.txtsą pozostawione same.

Czy jest jakiś sposób na osiągnięcie tego za pomocą rsync?

EDYCJA: Wydaje się, że werdykt może być niemożliwy w przypadku rsync. Zapytano mnie, dlaczego potrzebuję tego, aby zilustrować mój przypadek użycia:

Powiedzmy, że mam serwer internetowy. Na tym serwerze mam kilka katalogów, powiedzmy, że mam katalog Ai public_htmlkatalog, z którego obsługiwana jest moja strona. Powiedzmy, że mam zautomatyzowany proces, który tworzy pliki w katalogu A. Chciałbym rsync (lub synchronizacja za pomocą innego narzędzia) pliki wygenerowane lub aktualizowane w Ado public_htmlkatalogu, nie usuwając innych dowolnych plików, które mogą być w zasięgu public_html. Z pewnością nie chcę, aby rsync przypadkowo usunął moją witrynę.

Jeśli rsync nie jest narzędziem do tego zadania, czy ktoś inny wie, jak to zrobić?

Heather Miller
źródło
2
Po ponownym przeczytaniu pytania nie sądzę, aby było to możliwe, rsyncponieważ nie ma sposobu, aby dowiedzieć się, które pliki znajdują się już w folderze zdalnym. Może być konieczne znalezienie innego narzędzia.
Spack
rsync nie pozwoli ci tego zrobić, ale jeśli scpujesz cały katalog za każdym razem, gdy usuwasz pliki, możesz je zsynchronizować, nie jest to rozwiązanie tylko sugestia.
Aadi Droid
1
Zgaduję, że już o tym pomyślałeś, ale czy nie możesz po prostu umieścić tych plików w podkatalogu (lub gdzieś indziej) i odwołać się do nich z public_html? W ten sposób masz jeden katalog, który można łatwo i wyraźnie zsynchronizować, bez wpływu na pliki w innych częściach systemu plików serwera WWW.
MattJenko

Odpowiedzi:

2

To, co chcesz zrobić, jest rozsądne, ale korzystanie rsyncz niego samodzielnie nie jest. Więc odpowiedź brzmi nie .

Powód jest prosty: rsyncnie przechowuje historii tego, co było w każdym katalogu i nie ma możliwości dowiedzenia się, co należy usunąć, a co nie. Nie bez dodatkowego wsparcia.

Powinieneś zadać sobie pytanie, dlaczego lubisz to robić rsynci wyjaśnić. Istnieją inne programy, librsync1.soktóre są bardziej inteligentne.


Dzięki łagodnym ograniczeniom, których nie potrzebujesz rsync, możesz rzucić okiem na rdiff-backup :

mkdir a
touch a/xx
touch a/yy
rdiff-backup a b
ls b 

To pokazuje xxi yysą w b.

touch b/zz
rm a/xx
rdiff-backup a b

To pokazuje xxi zzsą w b. rdiff-backuprównież utrzymuje katalog rdiff-backup-dataw btak można cofnąć wszystkie zmiany, należy oczyścić to regularnie, używając rdiff-backuppolecenia. (Przykładem są pliki lokalne pokazujące, że dodatkowe dane w celu nie zostaną usunięte, ale rdiff-backup działa również przez sieć).


Inną alternatywą jest skonfigurowanie rozproszonego systemu kontroli wersji (mercurial, bazar, git). Z mercurial np. Możesz mieć skrypt (używam do tego Makefile), który wypycha wszystkie zmiany na serwer, a następnie dokonuje aktualizacji pobranych plików, ignoruje wszelkie dodatkowe pliki, które znajdują się na zdalnym serwerze (ale mają nie poddano kontroli wersji).

Na serwerze zrobiłbyś:

hg init
hg add file_list_excluding_that_should_not_should_be_deleted_if_not_on_client
hg commit -m "initial setup"

Na kliencie:

hg clone ssh://username@server/dir_to_repository

Teraz, jeśli usuniesz plik na kliencie i wykonasz:

hg commit -m "removed file"
ssh username@server "cd dir_to_repository; hg update --clean"

Usunięty plik zostanie usunięty na serwerze, ale żadne inne dane (nie dodane do repozytorium) nie zostaną usunięte.

Anthon
źródło
Mogę zaakceptować, że rsync tego nie zrobi. Ale nie zgadzam się, że byłoby to niemożliwe przy rsync - jeśli rsync wie po stronie wysyłającej, które pliki zostały usunięte, dlaczego nie może wysłać tej informacji do strony odbierającej w diff? Po porównaniu ze świeżością, nie rozumiem, dlaczego strona odbierająca nie może po prostu usunąć plików, które zostały wskazane do usunięcia w diff, bez usuwania całej reszty w katalogu. Usuwanie każdego innego (skasowanego u źródła) niewinnego pliku z katalogu wydaje mi się nieuzasadnione.
Heather Miller
W każdym razie powód, dla którego go potrzebuję, jest następujący. Mam katalog, nazwijmy go A, w którym proces jest zautomatyzowany, a pliki są tam generowane automatycznie. Mam serwer sieciowy i chciałbym, aby znajdujące się w nim pliki Azostały zsynchronizowane z public_htmlkatalogiem serwera, oczywiście bez usuwania wszystkiego innego w public_htmlfolderze serwera. Jeśli ktoś ma jakieś pomysły na osiągnięcie tego za pomocą innego narzędzia, byłoby to mile widziane. Zaktualizuję moje pytanie, aby to odzwierciedlić.
Heather Miller
Aby wyjaśnić mój pierwszy komentarz powyżej - powinienem powiedzieć: „Nie zgadzam się, że coś takiego powinno być niemożliwe przy użyciu narzędzia takiego jak rsync”. Intuicyjnie wydaje się, że osiągnięcie tego nie może być zbyt trudne (chyba że czegoś mi brakuje).
Heather Miller
Hmm ok. Wydaje mi się, że teraz rozumiem - skąd rsync może wiedzieć, kiedy coś zostało usunięte z local-srckatalogu, bez konieczności obserwowania zmian w tym katalogu. Może to byłoby trudne.
Heather Miller
@ HeatherMiller Jak napisałem, twoja prośba jest uzasadniona, ale rsyncnie jest narzędziem. Należy mieć świadomość, że syncw rsyncpochodzi z synchronizacji i to nie jest dokładnie to, co chcesz zrobić. W rozwoju rsyncskupiono się na wydajnym (minimalizowaniu) przekazywaniu danych. Inne narzędzia, takie jak rdiff-backup(i możliwe cvsup), wykorzystały do ​​tego swoje techniki, ale wykorzystują dodatkowe funkcje.
Anthon
1

Nie sądzę, że jest to możliwe bez jawnego wykluczenia plików po stronie odbierającej jako części polecenia rsync. Zobacz sekcję strony podręcznika dla rsync: „ZASADY I USUŃ DLA KATALOGU”.

Bez opcji usuwania reguły dla poszczególnych katalogów są istotne tylko po stronie wysyłającej, więc możesz swobodnie wykluczyć same pliki scalania bez wpływu na przesyłanie. Aby to ułatwić, modyfikator „e” dodaje to wykluczenie, jak widać w tych dwóch równoważnych poleceniach:

          rsync -av --filter=': .excl' --exclude=.excl host:src/dir /dest
          rsync -av --filter=':e .excl' host:src/dir /dest

Jeśli jednak chcesz usunąć po stronie odbierającej ORAZ chcesz, aby niektóre pliki zostały wykluczone z usunięcia, musisz upewnić się, że strona odbierająca wie, jakie pliki należy wykluczyć. Najłatwiejszym sposobem jest włączenie plików korespondencji seryjnej do przesyłania i użycie --delete-after, ponieważ zapewnia to, że strona odbierająca otrzyma wszystkie te same reguły wykluczania, co strona wysyłająca, zanim spróbuje coś usunąć:

          rsync -avF --delete-after host:src/dir /dest

Jeśli jednak pliki korespondencji seryjnej nie są częścią transferu, musisz albo podać niektóre globalne reguły wykluczania (tj. Określone w wierszu poleceń), albo musisz zachować własne pliki korespondencji seryjnej w katalogu strona odbiorcza. Przykładem pierwszego jest to (załóżmy, że zdalne pliki .rules się wykluczają):

   rsync -av --filter=’: .rules’ --filter=’. /my/extra.rules’
      --delete host:src/dir /dest

W powyższym przykładzie plik extra.rules może wpływać na obie strony transferu, ale (po stronie wysyłającej) reguły są podporządkowane regułom scalonym z plików .rules, ponieważ zostały określone po regule scalania dla poszczególnych katalogów.

W końcowym przykładzie strona zdalna wyklucza pliki .rsync-filter z transferu, ale chcemy użyć własnych plików .rsync-filter do kontroli tego, co zostanie usunięte po stronie odbierającej. Aby to zrobić, musimy wyraźnie wykluczyć pliki scalania dla poszczególnych katalogów (aby nie zostały usunięte), a następnie umieścić reguły w plikach lokalnych, aby kontrolować, co jeszcze nie powinno zostać usunięte. Jak jedno z tych poleceń:

       rsync -av --filter=':e /.rsync-filter' --delete \
           host:src/dir /dest
       rsync -avFF --delete host:src/dir /dest
slm
źródło
0

Jeśli dobrze zrozumiałem, --excludebyć może tego szukasz:

$ ls src dst
dst:
a.txt  b.txt  c.txt  d.txt  README.md

src:
c.txt
$ rsync --update --delete --recursive --exclude="d.txt" --exclude="README.md" src/ dst
$ ls src dst
dst:
c.txt  d.txt  README.md

src:
c.txt
Spack
źródło
Więc nie. Nie chcę ręcznie wymieniać wszystkich plików, które chciałbym wykluczyć. Chciałbym tylko, aby rsync usunął tylko pliki, które usunąłem u źródła - nie powinienem wiedzieć u źródła, jakie inne możliwe pliki istnieją w tym samym katalogu w miejscu docelowym.
Heather Miller
0

Mam na to odpowiedź. Myślę, że to działa. I to działa dla mnie. Najpierw musisz rsynczdalnie przesłać pliki do plików lokalnych. Następnie strona lokalna zawiera wszystkie pliki.

sudo rsync -r -a -v --delete /[email protected]:/remote_dir/ /local_dir/

teraz po stronie lokalnej

a.txt
b.txt
c.txt
d.txt
README.md

Następnie możesz usunąć pliki lub zrobić co chcesz. (Po stronie lokalnej). W swoim pytaniu usuwasz te pliki.

usunięte pliki

a.txt
b.txt

Następnie możesz rsyncprzenieść pliki lokalne na stronę zdalną, a następnie obie strony mają te same pliki.

sudo rsync -r -a -v --delete /local_dir/ [email protected]:/remote_dir/

to daje

c.txt
d.txt
README.md

pliki po stronie zdalnej i po stronie lokalnej (przy użyciu --deleteusuwa inne pliki po stronie zdalnej , które nie są zgodne ze stroną lokalną ).

Takitha Sumanadasa
źródło