Как я могу использовать rsync для дублирования дерева каталогов, создания жестких ссылок на файлы?

23

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

Тем не менее, я не могу заставить Rsync сделать это. Я пытался

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

но вместо создания жестких ссылок на файлы rsync копирует их полностью. Есть ли проблема при использовании одного и того же каталога источника и ссылки?

Жан-Филипп Пелле
источник

Ответы:

21

rsync это мощный инструмент, но, к сожалению, он странно требователен к некоторым из своих путей.

Если $DATAэто абсолютный путь (т. Е. Он начинается с a /), то правильной командной строкой будет:

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

[Теперь, коротко о rsyncстранности. Обратите внимание на трейлинг, /добавленный к исходному аргументу. Это говорит rsyncо работе с содержимым исходного каталога, а не с самим исходным каталогом. (Я предполагаю, что он $DATAеще не содержит трейлинг /.) В этом случае мы хотим работать с содержимым, поэтому мы добавляем трейлинг /.]

Если, с другой стороны, $DATAэто относительный путь (т. Е. Он не начинается с a /), то комментарий Sean R о --link-destbang on: путь link-dest интерпретируется относительно пути назначения , поэтому вы должны использовать следующее:

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

РЕДАКТИРОВАТЬ

И последнее замечание: оказывается, что вторая rsyncкомандная строка, которую я дал, должна работать независимо от того, $DATAявляется ли путь абсолютным, поскольку basenameне имеет значения, является ли путь абсолютным или относительным.

Стивен Понедельник
источник
1
Просто пропущенный слеш, кто бы мог подумать об этом ... Спасибо за хорошее объяснение!
Жан-Филипп Пелле
Спасибо вам за это, я попытался следовать нескольким инструкциям инкрементного резервного копирования, как этот, и не нашел упоминаний об этой причуде. Это было единственное, что фактически гарантировало жесткую ссылку на файлы. Проверка того, что количество ссылок было> 1, и номера инодов были ls -ilah
такими
Я использовал это вместе с функцией relpath (), описанной по адресу unix.stackexchange.com/a/85068/57414, для резервного копирования $SOURCEкаталога в каталог, $TARGETнапример:SOURCE='abs_path_to_backup'; TARGET='.'; rsync -a --link-dest=$(relpath $TARGET $SOURCE) $SOURCE/ $TARGET/
Натан С. Ватсон-Хей,
13

То, что вы хотите, это "cp -al":

cp -al $DATA/ $DATA/../upgrade_tmp/
  • рекурсивные как rsync -a
  • -l будет жестко связывать файлы, а не копировать их.
Шон Рейфшнайдер
источник
1
cp -alк сожалению, не доступен в моей системе (Mac OS X 10.6). Вместо этого я буду использовать pax ...
Жан-Филипп Пелле
7

Параметр --link-destin rsyncотносится к каталогу назначения , а не к текущему каталогу. Итак, что вы хотите, это:

rsync -a --link-dest=../`basename $DATA` $DATA $DATA/../upgrade_tmp
Шон Рейфшнайдер
источник
Ой, я имел в виду базовое имя, изначально у меня было dirname.
Шон Рейфшнайдер
1
Страница man говорит, что этот --link-destпараметр, если он относительный , относится к целевому каталогу. В моем случае это абсолютно. Даже создание его относительно целевого каталога не делает эту работу.
Жан-Филипп Пелле
7

Оказывается, это сложнее сделать с rsyncпомощью других инструментов. Правильный ответ rsync- Стивен Монаи, но самый простой способ сделать это - использовать один cp -alили pax -rwlв системах, где -lнедопустимый вариант для cp:

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

или

cp -al $DATA/ $DATA/../upgrade_tmp/
Жан-Филипп Пелле
источник
4

Меня устраивает:

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

Я использую rsync версии 3.1.0.

От мужчины :

--hard-ссылки

Сообщает rsync искать жестко связанные файлы в передаче, без этой опции жестко связанные файлы в передаче обрабатываются так, как если бы они были отдельными файлами.

--link-Dest = DIR

Неизмененные файлы жестко связаны из DIR в каталог назначения. Файлы должны быть идентичны по всем сохраненным атрибутам (например, права доступа, возможно, владение), чтобы файлы были связаны друг с другом.

Александр Федоров
источник
2
Только фрагмент кода не достаточно, объясните, что он делает и почему.
Петер говорит восстановить Монику
--hard-links Сообщает rsync искать жестко связанные файлы в передаче, без этой опции жестко связанные файлы в передаче обрабатываются так, как если бы они были отдельными файлами. --link-dest = DIR. Неизмененные файлы жестко связаны из DIR с целевым каталогом. Файлы должны быть идентичны по всем сохраненным атрибутам (например, права доступа, возможно, владение), чтобы файлы были связаны друг с другом.
Александр Федоров
1
Замечательно. Спасибо. На самом деле, я нашел ваш ответ в очереди "низкого качества". Это означает, что было проведено голосование, если ваш ответ должен быть удален или нет. Но не только опасность удаления является причиной, чтобы попытаться дать хорошо отформатированный, «человеческий» ответ, но и это очень помогает, если вы хотите собрать откаты.
говорит Петер, восстанови Монику
2

Можете попробовать перейти по ссылке http://www.lessfs.com/wordpress/ это работа на COW (копирование на запись), которая сэкономит время и пространство

Раджу
источник
Lessfs очень интересно, но также очень экспериментально. Пока не рекомендуется для производственного использования.
Mattdm
2

Сначала создайте каталоги только в месте назначения:

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

Затем жестко связать только файлы:

cd /source
find . -type f -exec ln -v {} /destination/{} \;
Cakemox
источник
Спасибо - на самом деле, я мог бы также использовать, paxкак показано в моем комментарии выше, что кажется проще.
Жан-Филипп Пелле
1

Используйте опцию -H, чтобы сохранить жесткие ссылки и прочитать справочную страницу.

текс
источник
1
-Н не работает. У меня нет жестких ссылок для сохранения в моем исходном дереве, я просто хочу простую копию моего исходного дерева, где в копии все файлы жестко связаны с исходными файлами. Извините, в моем первоначальном вопросе было неясно…
Жан-Филипп Пелле
«читать справочную страницу» - это ответ? :-)
meduz