Intereting Posts

rsync, удалите файлы на стороне получателя, которые были удалены на стороне отправки. (Но не удаляйте все)

Я хотел бы использовать rsync для …

  • удалять файлы на принимающей стороне, которые также были удалены на стороне отправки
  • не удалять другие файлы, находящиеся в rsynced каталоге на принимающей стороне

Например, допустим, у меня есть каталог local-src :

BEFORE: local-src локально содержит …

 a.txt b.txt c.txt 

мой удаленный каталог, который я хотел бы синхронизировать с содержимым local-src to, называется remote-src .

ДО: remote-src удаленно содержит …

 a.txt b.txt c.txt d.txt README.md 

Предположим, что я удаляю некоторые файлы в local-src :

ПОСЛЕ ЛОКАЛЬНОГО УДАЛЕНИЯ: local-src локально содержит …

 c.txt 

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

ПОСЛЕ ЛОКАЛЬНОГО УДАЛЕНИЯ: remote-src удаленно содержит …

 c.txt d.txt README.md 

То есть, a.txt и b.txt удаляются удаленно, но d.txt и README.txt остаются в d.txt .

Есть ли способ достичь этого с помощью rsync?

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

Предположим, у меня есть веб-сервер. На этом веб-сервере у меня есть куча каталогов, скажем, что у меня есть каталог A и каталог public_html , с которого мой сайт обслуживается. Предположим, что у меня есть автоматизированный процесс, который создает файлы в каталоге A Я хотел бы rsync (или синхронизировать с другим инструментом) файлы, сгенерированные или обновленные в A в каталог public_html , без удаления других произвольных файлов, которые могут быть в public_html . Я, конечно, не хочу, чтобы rsync случайно удалил мой сайт.

Если rsync не является инструментом для этой работы, знает ли кто-нибудь, как я могу это сделать?

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

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

Вы должны спросить себя, почему вы хотите сделать это с помощью rsync и сделать это более понятным. Существуют и другие программы, которые используют librsync1.so , которые более интеллектуальны.


С непринужденными ограничениями, которые вам не нужны rsync per se, вы можете взглянуть на rdiff-backup :

 mkdir a touch a/xx touch a/yy rdiff-backup ab ls b 

Это показывает, что xx и yy находятся в b .

 touch b/zz rm a/xx rdiff-backup ab 

Это показывает, что xx и zz находятся в b . rdiff-backup также сохраняет каталог rdiff-backup-data в b поэтому вы можете отменить любые изменения, вы должны регулярно rdiff-backup команд rdiff-backup . (Пример с локальными файлами, чтобы показать дополнительные данные в целевом, не удаляется, но rdiff-backup работает и по сети).


Другой альтернативой является настройка некоторой распределенной системы контроля версий (mercurial, bazaar, git). С mercurial, например, у вас может быть сценарий (я использую Makefile для этого), который подталкивает все изменения к серверу, а затем выполняет обновление извлеченных файлов там, игнорирует любые дополнительные файлы, которые находятся на удаленном сервере (но они имеют не подвергались контролю над пересмотром).

На сервере вы бы сделали:

 hg init hg add file_list_excluding_that_should_not_should_be_deleted_if_not_on_client hg commit -m "initial setup" 

На клиенте:

 hg clone ssh://username@server/dir_to_repository 

Теперь, если вы удалите файл на клиенте и выполните:

 hg commit -m "removed file" ssh username@server "cd dir_to_repository; hg update --clean" 

Удаленный файл удаляется на сервере, но любые другие данные (не добавленные в репозиторий) не удаляются.

Я не думаю, что это возможно без явного исключения файлов на принимающей стороне как часть команды rsync. См. Раздел справочной страницы для rsync: «ПРАВИЛА ПРЕРЫВАНИЯ И УДАЛЕНИЕ».

Без опции удаления правила для каждого каталога относятся только к стороне отправки, поэтому вы можете свободно исключать сами файлы слияния, не затрагивая передачу. Чтобы сделать это проще, модификатор 'e' добавляет это исключение для вас, как видно из этих двух эквивалентных команд:

  rsync -av --filter=': .excl' --exclude=.excl host:src/dir /dest rsync -av --filter=':e .excl' host:src/dir /dest 

Однако, если вы хотите сделать удаление на принимающей стороне. И вы хотите, чтобы некоторые файлы были исключены из удаления, вы должны быть уверены, что принимающая сторона знает, какие файлы следует исключить. Самый простой способ – включить файлы слияния для каждого каталога в передаче и использовать -delete-after, потому что это гарантирует, что принимающая сторона все равно исключает правила как отправную сторону, прежде чем пытается удалить что-либо:

  rsync -avF --delete-after host:src/dir /dest 

Однако, если файлы слияния не являются частью передачи, вам нужно либо указать некоторые глобальные правила исключения (т. Е. Указанные в командной строке), либо вам нужно будет сохранить свои собственные файлы слияния для каждого каталога на принимающая сторона. Примером первого является это (предположим, что удаленные файлы .rules исключают себя):

  rsync -av --filter=': .rules' --filter='. /my/extra.rules' --delete host:src/dir /dest 

В приведенном выше примере файл extra.rules может влиять на обе стороны передачи, но (на стороне отправки) правила подчиняются правилам, объединенным с файлами .rules, потому что они были указаны после правила слияния для каждого каталога.

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

  rsync -av --filter=':e /.rsync-filter' --delete \ host:src/dir /dest rsync -avFF --delete host:src/dir /dest 

Если я правильно понял, то --exclude может быть тем, что вы ищете:

 $ ls src dst dst: a.txt b.txt c.txt d.txt README.md src: c.txt $ rsync --update --delete --recursive --exclude="d.txt" --exclude="README.md" src/ dst $ ls src dst dst: c.txt d.txt README.md src: c.txt 

У меня есть ответ на этот вопрос. Я думаю, это работает. И это работает для меня. Сначала вам нужно будет rsync удаленных файлов в локальные файлы. Тогда локальная сторона содержит все файлы.

 sudo rsync -r -a -v --delete /root@xx.xx.xx.xx:/remote_dir/ /local_dir/ 

теперь в местной стороне

 a.txt b.txt c.txt d.txt README.md 

Затем вы можете удалить файлы или сделать все, что захотите (в локальной части). В вашем вопросе вы удаляете эти файлы.

удаленные файлы

 a.txt b.txt 

После этого вы можете rsync локальные файлы на удаленную сторону. Затем обе стороны имеют одинаковые файлы.

 sudo rsync -r -a -v --delete /local_dir/ root@xx.xx.xx.xx:/remote_dir/ 

это дает

 c.txt d.txt README.md 

файлы на удаленной стороне и на локальной стороне. (С помощью --delete удаляет другие файлы на удаленной стороне , которые не соответствуют локальной стороне ).