rsync, видаліть файли на стороні прийому, видалені на стороні надсилання. (Але не видаляйте все)


9

Я хотів би використовувати rsync для ...

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

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

ПЕРЕД: local-src локально містить ...

a.txt
b.txt
c.txt

local-srcназивається мій віддалений каталог, який я хотів би синхронізувати із вмістом 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залишили в спокої.

Чи є спосіб досягти цього за допомогою rsync?

РЕДАКТУВАННЯ: Здається, вирок може бути неможливим при rsync. Мене запитали, навіщо мені це потрібно, щоб проілюструвати мій приклад використання:

Скажімо, у мене є веб-сервер. На цьому веб-сервері у мене є маса каталогів, скажімо, що у мене є каталог Aі public_htmlкаталог, з якого обслуговується мій сайт. Скажімо, у мене є якийсь автоматизований процес, який виробляє файли в каталозі A. Я хотів би Rsync (або синхронізація з допомогою якого - або іншого інструменту) файли , створених або оновлених в Aв public_htmlкаталог, не видаляючи інші довільні файли , які можуть бути в межах public_html. Я, звичайно, не хочу, щоб rsync випадково видалив мій веб-сайт.

Якщо rsync не є інструментом для цієї роботи, чи хтось ще знає, як я можу це зробити?


2
Перечитавши ваше запитання, я не думаю, що це можливо, rsyncоскільки немає можливості знати, які файли, де вже є у віддаленій папці. Можливо, вам доведеться знайти інший інструмент.
Spack

rsync не дозволить вам цього робити, але якщо ви видаляєте весь каталог щоразу, коли ви видаляєте файли, ви можете тримати їх у синхронізації, а не рішення, а лише пропозиція.
Ааді Дроїд

1
Я здогадуюсь, ви вже про це думали, але чи не могли ви просто помістити ці файли у підкаталог (чи десь ще) та посилатися на них з public_html? Таким чином, у вас є один каталог, який легко і явно синхронізується, не впливаючи на файли в інших частинах файлової системи веб-сервера.
MattJenko

Відповіді:


2

Те, що ви хочете зробити, є розумним, але використовувати rsyncце самостійно - це не так. Тож відповідь - ні .

Причина проста: rsyncне зберігається історія того, що було у кожному каталозі, і не можна знати, що потрібно видалити, а що ні. Не без додаткової підтримки.

Ви повинні запитати себе, чому вам подобається це робити, rsyncі зробити це більш зрозумілим. Є й інші програми, які використовують librsync1.soбільш розумні.


Із розслабленими обмеженнями, які самі rsyncпо собі не потрібні , ви можете подивитися на rdiff-резервне копіювання :

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

Це показує xxі yyв b.

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

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


Інша альтернатива - встановити деяку розподілену систему контролю версій (mercurial, базар, 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- якщо rsync знає на стороні відправки, які файли було видалено, то чому вона не може надіслати цю інформацію приймаючій стороні у розл? Порівнюючи свіжість, я не бачу, чому приймаюча сторона не може просто видалити файли, які були вказані для видалення в розрізі, не видаляючи все інше в каталозі. Видалення будь-якого іншого (невизначеного у джерела) невинного файлу в каталозі мені здається нерозумним.
Хізер Міллер

У будь-якому випадку, мені це потрібно з причини. У мене є каталог, давайте назвемо його A, де деякий процес автоматизований, і там файли автоматично генеруються. У мене є веб-сервер, і я хотів би, щоб файли всередині Aбули спрямовані на public_htmlкаталог веб-сервера, звичайно, не видаляючи все інше в public_htmlпапці веб-сервера. Якщо у когось є якісь ідеї для досягнення цього за допомогою іншого інструменту, це було б більше ніж вітається. Я оновлю своє запитання, щоб це відобразити.
Хізер Міллер

Щоб уточнити свій перший коментар вище, я повинен був сказати: "Я не згоден, що щось подібне повинно бути неможливим із таким інструментом, як rsync". Інтуїтивно зрозуміло, що здається, що цього не може бути надто важко досягти (якщо я чогось не пропускаю).
Хізер Міллер

Хм, гаразд. Я думаю, я зараз бачу - як можна rsync знати, коли щось було видалено в local-srcкаталозі, не маючи певного процесу, щоб спостерігати за змінами в цьому каталозі. Можливо, це було б важко.
Хізер Міллер

@HeatherMiller Як я вже писав, ваш запит є розумним, але rsyncце не інструмент. Зверніть увагу, що syncв rsyncсинхронізації - це не те, що ви хочете робити. У процесі розвитку rsyncакцент робився на ефективній (мінімізації) передачі даних. Інші інструменти, такі як rdiff-backup(і можливі cvsup), використовували свої методи для цього, але будували на ньому додаткові функції.
Антон

1

Я не думаю, що це неможливо без явного виключення файлів на приймальній стороні як частини команди 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-фільтруючі файли для управління тим, що видаляється на стороні прийому. Для цього ми повинні спеціально виключити файли злиття для кожної каталоги (щоб вони не видалялися), а потім ввести правила у локальні файли, щоб контролювати те, що ще не слід видаляти. Як і одна з цих команд:

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

0

Якщо я правильно зрозумів, --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 видалив лише ті файли, які я видалив у джерелі. Я не повинен знати в джерелі, які інші можливі файли існують у тому самому каталозі пункту призначення.
Хізер Міллер

0

У мене є відповідь на це. Я думаю, що це працює. І це працює на мене. Спочатку вам доведеться 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, він видаляє інші файли на віддаленій стороні , які не збігаються з локальною стороною ).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.