Jak mogę użyć rsync do zduplikowania drzewa katalogów i utworzenia dowiązań twardych do plików?

23

Od czasu do czasu muszę wykonać kilka dużych zmian migracji plików danych na moim serwerze i szukam dobrego sposobu, aby to zrobić. Myślałem o użyciu rsync do zduplikowania mojej struktury katalogów, zaczynając od głównego katalogu danych, tworząc twarde linki do wszystkich oryginalnych plików (niektóre z nich są dość duże), i mogę zastąpić w drzewie docelowym tylko te pliki, które wymagają migracji. Na koniec mogę bezpiecznie przełączać się ze starych plików na nowe za pomocą dwóch mvoperacji.

Jednak nie wydaje mi się, aby rsync to zrobił. próbowałem

rsync -a --link-dest=$DATA $DATA $DATA/../upgrade_tmp

ale zamiast tworzyć twarde linki do plików, rsync kopiuje je całkowicie. Czy występuje problem z korzystaniem z tego samego katalogu źródłowego i docelowego?

Jean-Philippe Pellet
źródło

Odpowiedzi:

21

rsync to potężne narzędzie, ale niestety jest dziwnie wybredne w kwestii niektórych swoich ścieżek.

Jeśli $DATAjest to ścieżka bezwzględna (tzn. Zaczyna się na a /), to poprawnym wierszem poleceń jest:

rsync -a --link-dest=$DATA $DATA/ $DATA/../upgrade_tmp

[Teraz tylko krótki opis rsyncdziwności. Zwróć uwagę na końcowe /dodane do argumentu źródłowego. Mówi rsyncto o pracy z zawartością katalogu źródłowego, a nie z samym katalogiem źródłowym. (Zakładam, że $DATAnie zawiera on jeszcze końcowego /). W tym przypadku chcemy pracować z zawartością, więc dodajemy końcowy /.]

Jeśli, z drugiej strony, $DATAjest ścieżką względną (tzn. Nie zaczyna się od a /), to komentarz Seana R na temat --link-destbrzmi: Ścieżka link-dest jest interpretowana względem ścieżki docelowej , więc użyłbyś następujących:

rsync -a --link-dest=../`basename $DATA` $DATA/ $DATA/../upgrade_tmp

EDYTOWAĆ

Ostatnia uwaga: okazuje się, że drugi rsyncwiersz polecenia, który podałem, powinien działać niezależnie od tego, czy $DATAjest ścieżką bezwzględną, ponieważ basenamenie ma znaczenia, czy ścieżka jest bezwzględna, czy względna.

Steven Monday
źródło
1
Tylko brakujący ukośnik, kto by pomyślał o tym… Dzięki za miłe wyjaśnienie!
Jean-Philippe Pellet,
Dziękuję za to, próbowałem wykonać kilka instrukcji przyrostowych kopii zapasowych, takich jak ta, i nie znalazłem wzmianki o tym dziwactwie. To była jedyna rzecz, która zapewniła, że ​​pliki zostały połączone na stałe. Sprawdzanie, czy liczba ls -ilah
odwołań
Użyłem tego w połączeniu z funkcją relpath () opisaną na unix.stackexchange.com/a/85068/57414, aby wykonać kopię zapasową $SOURCEkatalogu w katalogu takim $TARGETjak ten:SOURCE='abs_path_to_backup'; TARGET='.'; rsync -a --link-dest=$(relpath $TARGET $SOURCE) $SOURCE/ $TARGET/
Nathan S. Watson-Haigh
13

Co chcesz to „cp -al”:

cp -al $DATA/ $DATA/../upgrade_tmp/
  • - nawroty jak rsync -a
  • -l będzie twarde linkować pliki zamiast je kopiować.
Sean Reifschneider
źródło
1
cp -aljest niestety niedostępny w moim systemie (Mac OS X 10.6). Zamiast tego użyję pax ...
Jean-Philippe Pellet
7

--link-destOpcja w rsyncjest w stosunku do docelowego katalogu, a nie w bieżącym katalogu. Więc czego chcesz to:

rsync -a --link-dest=../`basename $DATA` $DATA $DATA/../upgrade_tmp
Sean Reifschneider
źródło
Ups, miałem na myśli basename, pierwotnie miałem dirname.
Sean Reifschneider,
1
Strona man mówi, że ta --link-destopcja, jeśli jest względna , jest względna w stosunku do katalogu docelowego. W moim przypadku jest to absolutne. Nawet uczynienie go względnym do katalogu docelowego nie działa.
Jean-Philippe Pellet,
7

Okazuje się, że trudniej to zrobić za rsyncpomocą innych narzędzi. Prawidłowa odpowiedź rsyncbrzmi: Steven Monai, ale najłatwiejszym sposobem na to jest użycie jednego cp -allub pax -rwlw systemach, w których -lnie jest poprawna opcja dla cp:

pax -rwl $DATA $DATA/../upgrade_tmp

lub

cp -al $DATA/ $DATA/../upgrade_tmp/
Jean-Philippe Pellet
źródło
4

Mi to pasuje:

$ rsync --hard-links --recursive --link-dest=/local user@host:/remote/ /local

Używam rsync w wersji 3.1.0.

Od człowieka :

- twarde linki

Informuje rsync, aby szukał w przesyłaniu plików połączonych na stałe, bez tej opcji pliki połączone na stałe są przesyłane tak, jakby były osobnymi plikami.

--link-dest = DIR

Niezmienione pliki są trwale połączone z DIR do katalogu docelowego. Pliki muszą być identyczne we wszystkich zachowanych atrybutach (np. Uprawnieniach, ewentualnie własności), aby pliki mogły być ze sobą połączone

Aleksander Fiedorow
źródło
2
Tylko fragment kodu nie wystarczy, wyjaśnij, co robi i dlaczego.
Peter mówi, że przywróć Monikę
--hard-links Powiadamia rsync, aby szukał plików połączonych w trakcie przesyłania, bez tej opcji pliki połączone w trakcie przesyłania są traktowane tak, jakby były osobnymi plikami. --link-dest = DIR Niezmienione pliki są trwale połączone z DIR do katalogu docelowego. Pliki muszą być identyczne we wszystkich zachowanych atrybutach (np. Uprawnieniach, ewentualnie własności), aby pliki mogły być ze sobą połączone.
Aleksander Fiedorow
1
Wspaniale. Dziękuję Ci. Właściwie znalazłem twoją odpowiedź w kolejce „niskiej jakości”. Oznacza to, że głosowano, czy odpowiedź powinna zostać usunięta, czy nie. Ale nie tylko niebezpieczeństwo usunięcia jest powodem, aby spróbować udzielić dobrze sformatowanej, „ludzkiej” odpowiedzi, ale także bardzo pomaga, jeśli chcesz zebrać głosy poparcia.
Peter mówi, że przywrócenie Moniki
2

Można wypróbować następujący link http://www.lessfs.com/wordpress/ to działa na COW (kopiowanie przy zapisie), co pozwoli zaoszczędzić czas i miejsce

Rajat
źródło
lessfs jest bardzo interesujący, ale także bardzo eksperymentalny. Jeszcze nie zalecane do użytku produkcyjnego.
mattdm,
2

Najpierw utwórz katalogi tylko w miejscu docelowym:

rsync -av --include '*/' --exclude '*' /source/ /destination/

Następnie podłącz tylko twarde pliki:

cd /source
find . -type f -exec ln -v {} /destination/{} \;
Cakemox
źródło
Dzięki - właściwie równie dobrze mogę użyć, paxjak pokazano w moim komentarzu powyżej, co wydaje się łatwiejsze.
Jean-Philippe Pellet,
1

Użyj opcji -H, aby zachować Hardlinks i przeczytaj stronę podręcznika.

tex
źródło
1
-H nie działa. Nie mam żadnych twardych linków do zachowania w moim drzewie źródłowym, chcę tylko prostą kopię mojego drzewa źródłowego, gdzie w kopii wszystkie pliki są dowiązane do oryginalnych plików. Przepraszam w moim pierwotnym pytaniu było niejasne…
Jean-Philippe Pellet,
czy „przeczytaj stronę podręczną” jest odpowiedzią? :-)
Meduz