Jak skopiować katalogi z zachowaniem twardych linków?

40

Jak przenosić katalogi, które mają wspólne pliki z jednej partycji na drugą?

Załóżmy, że mamy zamontowaną partycję /mnt/Xz katalogami udostępniającymi pliki za pomocą dowiązań twardych. Jak przenieść takie katalogi na inną partycję, niech to będzie /mnt/Yz zachowaniem tych twardych dowiązań.

Aby lepiej zilustrować, co rozumiem przez „katalogi współdzielące pliki wspólne z dowiązaniami twardymi”, oto przykład:

# let's create three of directories and files
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
# and copy it with hardlinks
cp -r -l a hardlinks_of_a

Mówiąc ściślej, załóżmy, że całkowity rozmiar plików to 10G, a każdy plik ma 10 dowiązań twardych. Pytanie brzmi, jak przenieść go do miejsca docelowego za pomocą 10G (ktoś może powiedzieć o skopiowaniu go za pomocą 100G, a następnie uruchomieniu deduplikacji - nie o to pytam)

Grzegorz Wierzowiecki
źródło

Odpowiedzi:

29

Pierwsza odpowiedź: droga GNU

cp -aKopie GNU rekurencyjnie zachowują jak najwięcej struktury i metadanych. Zawarte są w nim twarde linki między plikami w katalogu źródłowym. Aby wybrać zachowanie twardego linku bez wszystkich innych funkcji -a, użyj --preserve=links.

mkdir src
cd src
mkdir -p a/{b,c,d}/{x,y,z}
touch a/{b,c,d}/{x,y,z}/f{1,2,3,4,5}
cp -r -l a hardlinks_of_a
cd ..
cp -a src dst
Alan Curry
źródło
3
+1 na tar, -1 za użycie argumentów specyficznych dla GNU dla cp.
WhyNotHugo
Dałeś trzy odpowiedzi w jednym. Czy możesz podzielić je na trzy, aby można je było komentować i oceniać osobno? (Wskazówka: Możesz to edytować, aby zostawić tylko jeden - na przykład „cp -a”. Później dodaj jeszcze dwa, dla „tar” i „pax”)
Grzegorz Wierzowiecki
1
@GrzegorzWierzowiecki dokonany podział
Alan Curry
6
@ Hugo: nie ma nic złego w używaniu argumentów specyficznych dla GNU do standardowych narzędzi. Wersje GNU są obecnie de facto standardem, a nawet gdy nie były wstępnie instalowane, powszechną praktyką było instalowanie narzędzi GNU (wiem, że zawsze tak robiłem - były po prostu lepsze niż np. Wersje solaris i * bsd i zapewniły spójność między różnymi * nixami). Prawdopodobnie dobrą praktyką jest wskazywanie GNUism, kiedy ich używasz, ale nie jest to wymagane. Również Grzegorz nie powiedział „nie na Linuksie”, więc rozsądnie jest założyć, że to środowisko, o którym mówi.
cas
1
@WhyNotHugo: W jaki sposób POSIX „może być bardziej standardowy?”. POSIX to rzeczy, które doprowadziły nas tam, gdzie jesteśmy. Czy wiesz, że wszystkie wersje systemu Windows od Windows NT są w pełni zgodne z POSIX? Mają ograniczenie długości ścieżki do 255 znaków podczas korzystania z funkcji we / wy pliku POSIX, co czyni je bezużytecznymi. Czy wiesz, że Solaris, Irix, HP-UX są zgodne z POSIX, a jednak wszystkie argumenty na ich narzędziach są różne (np. Tar). cp -a jest minimalnym wymaganiem dla każdej wersji cp, która chce zastąpić kopię GNU.
Johannes Overmann
36

rsync ma do tego opcję -Hlub --hard-links, i ma zwykłe zalety rsync polegające na tym, że można go zatrzymać i zrestartować, a także ponownie uruchomić, aby skutecznie radzić sobie z plikami, które zostały zmienione podczas / po poprzednim uruchomieniu.

-H, --hard-links
    This tells rsync to look for hard-linked files in
    the source and link together the corresponding
    files on the destination.  Without  this option,
    hard-linked files in the source are treated as
    though they were separate files. [...]

Przeczytaj rsyncstronę podręcznika man i wyszukaj -H. Jest o wiele więcej szczegółów na temat poszczególnych zastrzeżeń.

cas
źródło
2
Sprawdziłem - działa.
Grzegorz Wierzowiecki
tak, wiem. Używam go od lat w moich skryptach kopii zapasowych. także do przenoszenia plików między systemami plików, jak w pytaniu.
cas
rsync używa ogromnej ilości pamięci podczas budowania listy plików. Dla mnie po wielu godzinach „Budowania listy plików ...” zapełniło mnie 16 GB pamięci i nie zapłaciłem nic, że nic nie skopiowałem. YMMV.
msc
2
Od man rsync: Począwszy od rsync 3.0.0, stosowany algorytm rekurencyjny jest teraz skanem przyrostowym, który zużywa znacznie mniej pamięci niż wcześniej i rozpoczyna transfer po zakończeniu skanowania pierwszych kilku katalogów. Ten przyrostowy skan wpływa tylko na nasz algorytm rekurencyjny i nie zmienia transferu nierekurencyjnego. Jest to również możliwe tylko wtedy, gdy oba końce przesyłania są co najmniej w wersji 3.0.0. Zauważ, że oba te elementy --delete-beforei --delete-afterwyłącz ten ulepszony algorytm.
cas
Ponadto, choć rsyncjest również niezwykle przydatny, nie zawsze jest najlepszym narzędziem do każdej pracy. Obecnie wolę używać zestawów danych ZFS, aby móc tworzyć migawki i zfs sendje - najczęściej używam rsync na systemach plików nieobsługujących ZFS. btrfsma podobną funkcję migawki + wysyłania.
cas
14

Trzecia odpowiedź: sposób POSIX

POSIX nie ustandaryzował tarnarzędzia, chociaż ujednolicili tarformat archiwum. Wywoływane jest narzędzie POSIX do manipulowania archiwami tar paxi ma dodatkową funkcję polegającą na wykonywaniu operacji pakowania i rozpakowywania w jednym procesie.

mkdir dst
pax -rw src dst
Alan Curry
źródło
10

Druga odpowiedź: The Ancient UNIX Way

Utwórz archiwum tar w katalogu źródłowym, prześlij je przez potok i rozpakuj w katalogu docelowym.

# create src as before
(cd src;tar cf - .) | (mkdir dst;cd dst;tar xf -)
Alan Curry
źródło
1
zaznaczone -> działa. Hardlinks zachowane.
Grzegorz Wierzowiecki
1
Masz jakiś wgląd w to, dlaczego tak naprawdę zachowuje linki twarde?
peterph
1
Ponieważ tarzachowuje twarde linki. Przynajmniej w GNU tar możesz to wyłączyć, używając--hard-dereference
cas
W moim przypadku próba skopiowania dużej hierarchii katalogów (kopia zapasowa TimeMachine), tar zachowała niektóre twarde linki, ale w niektórych przypadkach zreplikowała plik. Myślę, że tar xdzieje się tak, ponieważ nie ma pełnej listy plików, ponieważ pliki są nadal przesyłane strumieniowo z tar c. Prawdopodobnie, jeśli zapisałeś całe archiwum przed wypakowaniem go, byłoby w porządku. Byłbym bardzo szczęśliwy, gdyby ktoś mógł potwierdzić tę teorię.
msc
10

Źródło: http://www.cyberciti.biz/faq/linux-unix-apple-osx-bsd-rsync-copy-hard-links/

Aby dokładnie wykonać kopię, potrzebujesz

rsync -az -H --delete --numeric-ids /path/to/source/ /path/to/dest/
Pykler
źródło
Zobacz mój komentarz na temat rsync powyżej.
msc
1
Podejrzewam, że nie spowoduje to skopiowania list ACL, rozszerzonych atrybutów itp. Wersja Linuksa ma również opcje -A i -X, aby je zachować, ale myślę, że nie masz szczęścia w MacOS.
Edward Falk,