Як скопіювати каталоги із збереженням жорстких посилань?


40

Як переміщувати каталоги, які мають спільні файли, з одного розділу на інший?

Припустимо, у нас встановлений розділ, на /mnt/Xякому розміщені каталоги, що обмінюються файлами з жорсткими посиланнями. Як перенести такі каталоги на інший розділ, нехай це буде /mnt/Yіз збереженням цих жорстких посилань.

Для кращої ілюстрації, що я маю на увазі під "каталогами, які спільно використовують файли, що містять жорсткі посилання", ось приклад:

# 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

Щоб бути більш конкретним, припустимо, що загальний розмір файлів становить 10G і кожен файл має 10 жорстких посилань. Питання полягає в тому, як перемістити його до місця призначення за допомогою 10G (хтось може сказати про його копіювання з 100G, а потім запуск дедуплікації - я не про це запитую)

Відповіді:


29

Перша відповідь: Шлях GNU

GNU cp -aкопіює рекурсивно, зберігаючи якомога більше структури та метаданих. У цьому включені жорсткі посилання між файлами у вихідному каталозі. Щоб вибрати збереження жорсткого посилання конкретно без усіх інших функцій -a, використовуйте --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

3
+1 на tar, -1 для використання gnu-специфічних аргументів для cp.
WhyNotHugo

Ви дали три відповіді в одній. Чи можете ви розділити їх на три, щоб вони могли коментуватися та оцінюватися окремо? (Порада: Ви можете відредагувати це, залишивши лише одне - наприклад, "cp -a". Пізніше додайте ще два, для "tar" та "pax")
Grzegorz Wierzowiecki

1
@GrzegorzWierzowiecki здійснено розкол
Алан Керрі

6
@Hugo: немає нічого поганого у використанні специфічних для GNU аргументів для стандартних інструментів. Версії GNU є де-факто стандартними в наші дні, і навіть коли вони не були попередньо встановлені, звичайною практикою було встановлення інструментів GNU (я знаю, що я завжди робив - вони були просто кращими, ніж, наприклад, версії solaris та * bsd , і вони забезпечували узгодженість між різними * ніксами). Напевно, є хорошою практикою вказувати на GNUisms, коли ви їх використовуєте, але не потрібно. Крім того, Гжегож не сказав "не на Linux", тому розумно припустити, що це таке середовище, про яке він говорить.
cas

1
@WhyNotHugo: Як POSIX "може бути більш стандартним?". POSIX - це матеріал, який привів нас там, де ми є. Чи знаєте ви, що всі версії Windows після Windows NT повністю сумісні з POSIX? У них обмеження довжини шляху 255 символів при використанні функцій вводу / виводу файлу POSIX, що робить їх марними. Чи знаєте ви, що Solaris, Irix, HP-UX сумісні з POSIX, але все ж аргументи до їхніх інструментів відрізняються (наприклад, tar). cp -a - мінімальна вимога для будь-якої версії cp, яка хоче замінити копію GNU.
Йоганнес Оверманн

36

rsync має -Hабо --hard-linksдля цього варіант, і має звичні переваги rsync від можливості зупинки та перезапуску, а також для повторного запуску для ефективної обробки будь-яких файлів, які були змінені під час / після попереднього запуску.

-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. [...]

Прочитайте сторінку rsyncman і знайдіть -H. Існує набагато більше деталей щодо конкретних застережень.


2
Я перевірив - працює.
Grzegorz Wierzowiecki

так, я знаю. Я використовую його протягом багатьох років у своїх резервних скриптах. також переміщувати файли між файловими системами, як у вашому запитанні.
cas

rsync використовує геб пам'яті під час створення свого списку файлів. Для мене після багатьох годин "Створення списку файлів ..." він заповнив мою 16 Гб пам'яті і під заставу нічого не скопіював. YMMV.
msc

2
Від man rsync: Починаючи з rsync 3.0.0, використовуваний рекурсивний алгоритм - це покрокове сканування, яке використовує набагато менше пам’яті, ніж раніше, і розпочинає передачу після того, як сканування перших кількох каталогів завершено. Це покрокове сканування впливає лише на наш алгоритм рекурсії і не змінює нерекурсивний перехід. Це також можливо лише тоді, коли обидва кінці передачі мають принаймні версію 3.0.0. Зауважте, що --delete-beforeі --delete-afterвідключити цей покращений алгоритм.
cas

Крім того, хоча rsyncце також неймовірно корисно, але це не завжди найкращий інструмент для кожної роботи. У наші дні я вважаю за краще використовувати набори даних ZFS, щоб я міг робити знімки та zfs sendїх - я в основному використовую rsync у файлових системах, що не належать до ZFS. btrfsмає подібний знімок + можливість надсилання.
cas

14

Третя відповідь: POSIX шлях

POSIX не стандартизував tarутиліту, хоча вони стандартизували tarформат архіву. Викликається утиліта POSIX для маніпулювання архівами смоли, paxі вона має бонусну функцію за можливість виконувати операції пакування та розпакування в одному процесі.

mkdir dst
pax -rw src dst

10

Друга відповідь: Стародавній шлях UNIX

Створіть архів дьогтю у вихідному каталозі, надішліть його по трубі та розпакуйте його в каталозі призначення.

# create src as before
(cd src;tar cf - .) | (mkdir dst;cd dst;tar xf -)

1
перевірено -> працює. Жорсткі посилання збереглися.
Grzegorz Wierzowiecki

1
Будь-яке розуміння того, чому це насправді зберігає жорсткі посилання?
петерф

1
Тому що tarзберігає жорсткі зв’язки. Принаймні, у --hard-dereference
таріумі

У моєму випадку, намагаючись скопіювати велику ієрархію каталогів (резервна копія TimeMachine), tar зберігав деякі жорсткі посилання, але реплікував файл у деяких випадках. Я думаю, що це тому, що у них tar xнемає повного списку файлів, оскільки файли все ще передаються з tar c. Можливо, якби ви зберегли весь архів перед тим, як витягти його, було б добре. Я був би дуже радий, якби хтось міг підтвердити цю теорію.
msc

10

Джерело: http://www.cyberciti.biz/faq/linux-unix-apple-osx-bsd-rsync-copy-hard-links/

Те, що вам потрібно зробити точну копію, - це

rsync -az -H --delete --numeric-ids /path/to/source/ /path/to/dest/

Дивіться мій коментар про rsync вище.
msc

1
Я підозрюю, що це не буде копіювати ACL, розширені атрибути тощо. У версії Linux також є параметри -A і -X, щоб зберегти їх, але я думаю, що вам не пощастило в MacOS.
Едвард Фолк
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.