Как скопировать каталоги с сохранением жестких ссылок?


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

Чтобы быть более конкретным, давайте предположим, что общий размер файлов составляет 10 ГБ, и каждый файл имеет 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.
Йоханнес Оверманн

37

Для этого 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. [...]

Прочитайте rsyncсправочную страницу и найдите -H. Там есть намного больше деталей о конкретных предостережениях.


2
Я проверил - это работает.
Гжегож Вежовецкий

да, я знаю. Я использовал это в течение многих лет в моих сценариях резервного копирования. также для перемещения файлов между файловыми системами, как в вашем вопросе.
Cas

rsync использует объемы памяти при построении списка файлов. Для меня после многих часов «Построения списка файлов ...» он заполнил мои 16 ГБ памяти и выручил, ничего не скопировав. YMMV.
Мск

2
From man rsync: Начиная с rsync 3.0.0, используемый рекурсивный алгоритм теперь представляет собой инкрементное сканирование, которое использует намного меньше памяти, чем раньше, и начинает передачу после завершения сканирования первых нескольких каталогов. Это инкрементное сканирование влияет только на наш алгоритм рекурсии и не меняет нерекурсивную передачу. Это также возможно только тогда, когда оба конца переноса имеют версию не ниже 3.0.0. Обратите внимание, что оба --delete-beforeи --delete-afterотключить этот улучшенный алгоритм.
Cas

Кроме того, хотя rsyncэто невероятно полезно, это не всегда лучший инструмент для каждой работы. В настоящее время я предпочитаю использовать наборы данных ZFS, чтобы я мог делать снимки и zfs sendих - в основном я использую rsync в файловых системах, отличных от ZFS. btrfsимеет похожий снимок + возможность отправки.
Cas

14

Третий ответ: POSIX Way

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

mkdir dst
pax -rw src dst

10

Второй ответ: Древний путь UNIX

Создайте архив tar в исходном каталоге, отправьте его по каналу и распакуйте в целевой каталог.

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

1
проверил -> работает. Жесткие ссылки сохранены.
Гжегож Вежовецкий

1
Любое понимание, почему это на самом деле сохраняет жесткие ссылки?
Петер

1
Потому что tarсохраняет жесткие ссылки. В GNU tar, по крайней мере, вы можете отключить это поведение с помощью--hard-dereference
cas

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

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 выше.
Мск

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