rsync wyklucz katalog nie działa

34

Używam Fedory 17 64-bit i rsync --exclude=/home/ben/<dir>nie działa zgodnie z oczekiwaniami.

Próbuję z rsyncmojego katalogu domowego na pamięć USB, ale z pewnością chcę wykluczyć katalogi, które przechowują pliki pamięci podręcznej i budują pliki. Oto polecenie, którego używam:

rsync --exclude=/home/ben/build/ --exclude=/home/ben/.ccache -arv /home/ben home-ben/

Jednak treść z ~/buildi ~/.ccachejest kopiowana przez rsync. Co ja robię źle?

Freedom_Ben
źródło
1
Myślę, że wzorce wykluczania po prostu nie działają.
Sören,

Odpowiedzi:

37

Globalne rsyncreguły filtrów rozpoczynające się od wiodącego /zakotwiczone w rdzeniu transferu. Cytując z sekcji „OBEJMUJ / WYŁĄCZ ZASADY WZORU” strony podręcznika:

jeśli wzorzec zaczyna się od a, to jest zakotwiczony w określonym miejscu w hierarchii plików, w przeciwnym razie jest dopasowywany do końca nazwy ścieżki. Jest to podobne do wiodącego ^ wyrażeń regularnych. Zatem „/ foo” pasuje do nazwy „foo” w „katalogu głównym transferu” (dla reguły globalnej) lub w katalogu pliku scalania (dla reguły dla jednego katalogu).

W twojej komendzie ( rsync ... -arv /home/ben home-ben/) plik /home/ben/foozostanie przeniesiony do home-ben/ben/foo. Podstawą transferu jest, home-bena poprawna ścieżka filtru to /ben/foo. A zatem,

  • do dopasowania /home/ben/.ccachepotrzebujesz ścieżki filtru/ben/.ccache
  • do dopasowania /home/ben/build/potrzebujesz ścieżki filtru/ben/build/

Bardziej szczegółowe wyjaśnienie można znaleźć w sekcji „KOTWICZANIE OBEJMUJ / WYKLUCZ WZORY” na rsync(1)stronie podręcznika .


Pamiętaj, że zwykłe pominięcie wiodącej pozycji /niekoniecznie jest tym, czego chcesz. Cytując ponownie z tej samej sekcji strony podręcznika:

Niewykwalifikowane „foo” pasowałoby do nazwy „foo” w dowolnym miejscu drzewa, ponieważ algorytm jest stosowany rekurencyjnie od góry do dołu; zachowuje się tak, jakby każdy składnik ścieżki zmieniał się na końcu nazwy pliku. Nawet niezakotwiczone „sub / foo” pasowałoby do dowolnego punktu w hierarchii, w którym znaleziono „foo” w katalogu o nazwie „sub”. Zobacz sekcję KOTWICZANIE OBEJMUJĄ / WYKLUCZAJĄCE WZORY, aby uzyskać pełne omówienie sposobu określania wzoru pasującego w katalogu głównym transferu.

Zatem wzór filtr build/będzie pasował do nigdzie w katalogu build /home/ben, nawet /home/ben/many/sub/directories/build/.

jw013
źródło
2
Kluczowym szczegółem jest to, że cięcie ma znaczenie. Jeśli dodasz ukośnik na końcu katalogu źródłowego (rsync -a source / destination), skopiuje on zawartość źródła, w przeciwnym razie sam rsync -a source destinationskopiuje katalog źródłowy do miejsca docelowego. Określa to, czym będzie rdzeń przeniesienia, aby poinformować wyrażenie wykluczające. Właściwe użycie / w wyrażeniu wykluczającym jest następnie wyjaśnione powyżej. Zwróć uwagę, że rsync --exclude='/dir1' source destinationto niczego nie wyklucza.
pgoetz
11

Myślę, że twoje excludeścieżki muszą być względne względem ścieżki źródłowej. Możesz zamiast tego spróbować?

rsync --exclude=build/ --exclude=.ccache -arv /home/ben home-ben/

Oto test do porównania:

/tmp$ tree src dest
src
├── a
└── b
dest
└── foo/

/tmp$ rsync -nav --exclude /tmp/src/b /tmp/src /tmp/dest
sending incremental file list
src/
src/a
src/b

$ rsync -nav --exclude b /tmp/src /tmp/dest
sending incremental file list
src/
src/a
HorsePunchKid
źródło
2
Ta odpowiedź jest zła. Dzięki względnej ścieżce wykluczania wzór zostałby wykluczony wszędzie!
rubo77
Ten post jest poprawny. Dopasowanie jest oparte na tekście, a nie na plikach i-węzłów. Jakakolwiek ścieżka --verbosepokazuje wynik polecenia, to format, którego musisz użyć.
Sridhar Sarnobat
To zadziałało dla mnie.
Żenia
Co jeśli ścieżka źródłowa to „/”, to absolutne są ścieżki względne, ale nadal nie działa.
Sören,
To jedyna rzecz, która działała dla mnie.
Jonathan
2

Miałem ten problem w skrypcie (nie wiem, czy to twoja sprawa). Byłem, ponieważ użyłem tego polecenia w skrypcie i użyłem sh zamiast bash. sprawdź shebang na początku skryptu.

Jaoued Zahraoui
źródło
1

Wzorzec wykluczenia działałby, gdybyś zsynchronizował całą ścieżkę / home, tj. Bez końcowego ukośnika:

rsync --exclude=/home/ben/build/ --exclude=/home/ben/.ccache -arv /home home-all/

Ale lepiej tylko synchronizować zawartość folderu z ukośnikiem:

rsync --exclude=/build --exclude=/.ccache -arv /home/ben/ home-ben/

Możesz również użyć listy ignorowanych, patrz: https://askubuntu.com/questions/545655/backup-your-home-directory-with-rsync-and-skip-useless-folders

rubo77
źródło
0

Aby wykluczyć folder specif za pomocą rsync, należy rozważyć ścieżkę względną w poleceniu. w twoim przypadku:

rsync --exclude=/ben/build/ --exclude=/ben/.ccache -arv /home/ben home-ben/

gdzie „ben” to folder, który synchronizujesz

Samoht Rusconi
źródło