Рейтинг:0

rsync каталог со своим потомком

флаг gr

тл; др: я хочу rsync каталог своему потомку, а затем rsync указанный потомок обратно в исходный каталог, включая удаления и исключения в обоих направлениях.

Прежде чем вы зададите очевидный вопрос: «Зачем вам это нужно?» или укажите, насколько лучше был бы другой подход, это требование бизнеса. Это не мой выбор, и я осознаю риски, так что просто побалуйте меня. Я не намерен дальше оправдывать свой подход.

Подробности:

я хочу rsync каталог своему собственному потомку, т. е. каталог "под" или "внутри" его, например родитель к родитель/ребенок, например, а затем синхронизировать изменения в потомке обратно в исходный каталог, например, родитель/ребенок к родитель, включая удаления и исключения в обоих направлениях. Визуально мне нужно сделать так:

родитель -> родитель/потомок
родитель <- родитель/потомок

Трудности заключаются в...

  1. Предотвратить бесконечную рекурсию при переходе от предка к потомку
  2. Не удалять исходные файлы в середине операции при синхронизации потомка с его предком (проявляется как ошибка «файл исчез»).
  3. Всегда соблюдайте исключения
Рейтинг:0
флаг gr

Решение состоит из трех частей. Чтобы...

  1. Исключить путь к дочернему каталогу относительно предка, например, ребенок при синхронизации с родитель/ребенок
  2. Использовать --удалить-после флаг вместо --удалять
  3. Сделайте все пути исключения относительно источника, например, исключить.txt в отличие от /var/www/parent/exclude.txt

Вот тестовый скрипт (со специальным форматированием для более приятного вывода):

#!/usr/bin/env bash

чистый

printf "\n\e[33mrsync версия:\n"
printf "%s--------------\e[39m\n"

rsync --версия | голова -n 1
# rsync версии 2.6.9 протокол версии 29

rm -r родитель

mkdir -p родитель

коснитесь родительского/оригинального.txt \
      родитель/удалить-из-дочернего.txt \
      родитель/исключить-из-ребенка.txt

printf "\n\e[33mИсходное состояние:\n"
printf "%s---------------\e[39m\n"

дерево -a --noreport -- родитель

printf "\n\e[33mrsync для дочернего элемента:\n"
printf "%s---------------\e[39m\n"

printf "rsync --archive \n --delete-after \n --exclude=exclude-from-child.txt \n "$PWD"/родительский/ \n "$PWD"/родительский/дочерний\ п\п"
rsync --архив \
      --удалить-после \
      --exclude=exclude-from-child.txt \
      "$PWD"/родительский/ \
      "$PWD"/родитель/ребенок

дерево -a --noreport -- родитель; эхо

printf "\e[33mВнести изменения:\n"
printf "%s---------------\e[39m\n"

rm родитель/дочерний/удалить-от-дочернего.txt
printf "rm родитель/дочерний/удалить-из-дочернего.txt\n"
touch parent/child/create-in-child.txt
printf "коснитесь родительского/дочернего/создать-в-дочернем.txt\n"
коснитесь родительского/дочернего/exclude-from-parent.txt
printf "коснитесь родительского/дочернего/исключить-из-родителя.txt\n\n"

printf "\e[33mrsync обратно к родителю:\n"
printf "%s------------------------------------\e[39m\n"

printf "rsync --archive \n --delete-after \n --exclude=child \n --exclude=exclude-from-child.txt \n --exclude=exclude-from-parent.txt \n "$PWD"/родительский/дочерний/ \n "$PWD"/родительский\n\n"
rsync --архив \
      --удалить-после \
      --exclude=ребенок \
      --exclude=exclude-from-child.txt \
      --exclude=exclude-from-parent.txt \
      "$PWD"/родительский/дочерний/ \
      "$PWD"/родитель

дерево -a --noreport -- родитель; эхо
# Или `найти родителя -type f; echo`, если у вас нет `дерева`

printf "%s\n\e[33mОкончательное сравнение:\n"
printf "%s-----------------\e[39m\n"

diff --exclude=child parent parent/child; эхо

Вывод:

версия rsync:
--------------
rsync версии 2.6.9 протокол версии 29

Исходное состояние:
---------------
родитель
âââ delete-from-child.txt
âââ exclude-from-child.txt
âââ оригинальный.txt

rsync для ребенка:
---------------
rsync --архив
      --удалить-после
      --exclude=exclude-from-child.txt
      /var/www/родительский/
      /var/www/родитель/ребенок

родитель
ââ ребенок
â Â Â â â â delete-from-child.txt
âââ original.txt
âââ delete-from-child.txt
âââ exclude-from-child.txt
âââ оригинальный.txt

Вносить изменения:
---------------
rm родитель/дочерний/удалить-от-дочернего.txt
touch parent/child/create-in-child.txt
коснитесь родительского/дочернего/exclude-from-parent.txt

rsync обратно к родителю:
---------------------
rsync --архив
      --удалить-после
      --exclude=ребенок
      --exclude=exclude-from-child.txt
      --exclude=exclude-from-parent.txt
      /var/www/родитель/ребенок/
      /var/www/родительский

родитель
ââ ребенок
âââ create-in-child.txt
â  âââ exclude-from-parent.txt
âââ original.txt
âââ create-in-child.txt
âââ exclude-from-child.txt
âââ оригинальный.txt


Окончательное сравнение:
------------------
Только в родительском: exclude-from-child.txt
Только в родительском/дочернем: exclude-from-parent.txt
Рейтинг:0
флаг pk

Другой подход состоит в том, чтобы настроить монтирование привязки и, таким образом, сделать два дерева независимыми, а затем выполнить rsync как обычно:

mkdir/мнт/родитель
mkdir /mnt/ребенок
мкдир /mnt/пустой
mount --bind /путь/к/родительскому/дочернему /mnt/дочернему
mount --bind /path/to/parent /mnt/parent
mount --bind /mnt/пустой /mnt/родительский/дочерний

Теперь, когда вы делаете

rsync [аргументы] /mnt/parent/. /мнт/ребенок/.

пустой каталог /мнт/пусто будет маскировать настоящее /путь/к/родительскому/дочернему справочник; /мнт/родитель/ребенок будет казаться пустым и позволит избежать бесконечной рекурсии.

Когда вы делаете

rsync [аргументы] /mnt/child/. /мнт/родитель/.

ситуация будет аналогичной; /мнт/ребенок/ребенок/ будет пустым (поскольку вы ничего туда не копируете), и /мнт/родитель/ребенок/ также будет отображаться пустым, поэтому нет риска что-либо удалить оттуда.

Это, возможно, менее элегантно, чем решение @TravisCarden, но, возможно, более надежное.

флаг gr
Как интересно! К сожалению, я не могу рассчитывать на то, что моя конкретная целевая аудитория будет иметь доступ к mount, иначе я бы попробовал это, но спасибо за идею!

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.