rsync, alıcı taraftaki gönderen taraftaki dosyaları siler. (Ama her şeyi silmeyin)


9

Rsync'i şu amaçlarla kullanmak istiyorum ...

  • alıcı taraftaki gönderen tarafta da silinen dosyaları sil
  • alıcı tarafında rsynced dizininde bulunan diğer dosyaları silmeme

Örneğin, bir dizinim olduğunu varsayalım local-src:

ÖNCE: local-src yerel olarak içerir ...

a.txt
b.txt
c.txt

ile içeriğini senkronize etmek istediğim uzak dizinim local-srcçağrılıyor remote-src.

ÖNCE: remote-src uzaktan içerir ...

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

Diyelim ki bazı dosyaları siliyorum local-src:

YEREL SİLME SONRASI: local-src yerel olarak ...

c.txt

Kaynakta silinen dosyaların hedefte, ancak hedefteki diğer dosyaları silmeden silinmesini sağlayacak şekilde rsync'i nasıl kullanabilirim. Örneğin, hedefte aşağıdakilere sahip olmak istiyorum:

YEREL SİLME SONRASI: remote-src uzaktan ...

c.txt
d.txt
README.md

Yani, a.txtve b.txtuzaktan da silinir fakat d.txtve README.txtyalnız bırakılır.

Bunu rsync ile başarmanın bir yolu var mı?

EDIT: Karar rsync ile bu imkansız olabilir gibi görünüyor. Kullanım durumumu göstermek için buna neden ihtiyacım olduğu soruldu:

Diyelim ki bir web sunucum var. Bu web sunucusunda, bir dizin dizinim var, diyelim ki bir dizin Ave public_htmlsitemin sunulduğu bir dizin var. Dizin içinde dosya üreten bazı otomatik işlemlerim olduğunu varsayalım A. Ben rsync gibi (veya senkronizasyon diğer bazı araç kullanarak) oluşturulan veya dosyaları ediyorum güncellenen içinde Ahiç public_htmldahilinde olabilecek diğer keyfi dosyaları silmeden, dizindeki public_html. Kesinlikle rsync web sitemi yanlışlıkla silmesini istemiyorum.

Rsync bu iş için bir araç değilse, başka biri bunu nasıl yapabileceğimi biliyor mu?


2
Sorunuzu yeniden okuduktan sonra rsync, bunun uzak klasörde nerede olduğunu bilmenin bir yolu olmadığından bunun mümkün olduğunu düşünmüyorum . Başka bir araç bulmanız gerekebilir.
Spack

rsync bunu yapmanıza izin vermez, ancak dosyaları her sildiğinizde tüm dizini scp yaparsanız, bunları bir çözüm değil, senkronize tutabilirsiniz.
Aadi Droid

1
Bunu zaten düşündüğünüzü tahmin ediyorum, ancak bu dosyaları bir alt dizine (veya başka bir yere) koyamadınız ve public_html'den referans alamazdınız mı? Bu şekilde, web sunucusunun dosya sisteminin diğer bölümlerindeki dosyaları etkilemeden kolayca ve açıkça senkronize edilen bir dizine sahip olursunuz.
MattJenko

Yanıtlar:


2

Yapmak istediğiniz şey makul, ancak rsyncbunu kendi başına kullanmak değil. Yani cevap hayır .

Nedeni basit: rsyncher bir dizinde ne olduğuna dair hiçbir geçmiş tutar ve neyin silinip neyin silinmeyeceğini bilmenin bir yolu yoktur. Ek destek olmadan olmaz.

Kendinize bunu neden yapmak istediğinizi sormalı rsyncve bunu daha net hale getirmelisiniz. librsync1.soDaha akıllı olan başka programlar da var .


Kendi başınıza ihtiyacınız olmayan rahat kısıtlamalar rsyncile rdiff-backup'a göz atabilirsiniz :

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

Bu gösterir xxve yyiçinde b.

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

Bu gösterir xxve zziçinde b. rdiff-backupAyrıca bir dizin tutar rdiff-backup-dataiçinde bherhangi bir değişiklik geri alma böylece, kullandığınız düzenli olarak bu tasfiye etmelidir rdiff-backupkomutları. (Örnek, hedefte fazladan veri göstermek için yerel dosyalarda silinmez, ancak rdiff-backup bir ağ üzerinde de çalışır).


Diğer bir alternatif ise bazı dağıtılmış revizyon kontrol sistemi kurmaktır (mercurial, bazaar, git). Mercurial ile örneğin, bir sunucuya sahip olabilirsiniz (bunun için bir Makefile kullanıyorum), sunucudaki tüm değişiklikleri iter ve sonra orada teslim alınan dosyaların bir güncellemesini yapar, uzak sunucudaki ek dosyaları yok sayar (ancak revizyon kontrolü altına alınmamıştır).

Sunucuda şunları yapabilirsiniz:

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

İstemcide:

hg clone ssh://username@server/dir_to_repository

Şimdi istemcideki bir dosyayı kaldırır ve şunları yaparsanız:

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

Kaldırılan dosyanız sunucudan kaldırılır, ancak diğer veriler (depoya eklenmez) silinmez.


RSync'in bunu yapmayacağını kabul edebilirim. Ama rsync ile bunun imkansız olacağını kabul etmiyorum- eğer rsync gönderen tarafta hangi dosyaların silindiğini biliyorsa, neden bu bilgiyi farktaki alıcı tarafa gönderemez? Tazelik için karşılaştırma yaptıktan sonra, alıcı tarafın neden dizindeki diğer her şeyi silmeden fark içinde silinmesi belirtilen dosyaları silemediğini anlamıyorum. Dizindeki diğer (kaynakta silinen) masum dosyaları silmek benim için mantıksız görünüyor.
Heather Miller

Her durumda, buna ihtiyacımın nedeni şu. Ben bir dizin var, diyelim A, bazı süreç otomatik ve dosyaları otomatik olarak orada oluşturulur. Bir web sunucum var ve Aiçerideki dosyaların web sunucusunun public_htmldizinine yeniden bağlanmasını istiyorum , elbette public_htmlweb sunucusunun klasöründeki diğer her şeyi silmeden . Herkes başka bir araçla bunu başarmak için herhangi bir fikir varsa, bu hoş geldiniz daha fazla olacaktır. Sorumu bunu yansıtacak şekilde güncelleyeceğim.
Heather Miller

Yukarıdaki ilk yorumumu açıklığa kavuşturmak için - "Böyle bir şeyin rsync gibi bir araçla imkansız olması gerektiğine katılmıyorum" demeliydim. Sezgisel olarak, bunun başarılması çok zor görünmüyor gibi görünüyor (bir şeyi kaçırmadıkça).
Heather Miller

Hmm tamam. Ben şimdi görüyorum düşünüyorum - nasıl bir local-srcdizini değişiklikler için bu dizini izlerken bir işlem olmadan dizinde bir şey silindi biliyorum . Belki bu zor olurdu.
Heather Miller

@HeatherMiller Yazdığım gibi, talebiniz makul, ancak rsyncaraç değil. Fark edin syncde rsyncsenkronize geliyor ve bu yapmak istediğiniz şey bu değildi. rsyncOdaklanmanın geliştirilmesinde veri aktarımı verimli (minimize) olmuştur. Bunun gibi rdiff-backup(ve olası cvsup) diğer araçlar da tekniklerini kullanmış, ancak ek özelliklerle geliştirmiştir.
Anthon

1

Ben rsync komutunun bir parçası olarak alıcı taraftaki dosyaları açıkça hariç tutmadan bu mümkün olduğunu sanmıyorum. Rsync için kılavuz sayfasına bakınız: "BAŞKA YÖN KURALLARI VE SİL".

Silme seçeneği olmadan, dizin başına kurallar yalnızca gönderen tarafta geçerlidir, bu nedenle birleştirme dosyalarını aktarımı etkilemeden hariç tutabilirsiniz. Bunu kolaylaştırmak için, 'e' değiştiricisi, bu iki eşdeğer komutta görüldüğü gibi, sizin için bu hariç tutmayı ekler:

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

Ancak, alıcı tarafta bir silme işlemi yapmak istiyorsanız VE bazı dosyaların silinmesini hariç tutmak istiyorsanız, alıcı tarafın hangi dosyaların hariç tutulacağını bildiğinden emin olmanız gerekir. En kolay yol, dizin başına birleştirme dosyalarını aktarmaya dahil etmek ve --delete-after komutunu kullanmaktır, çünkü bu, alıcı tarafın herhangi bir şeyi silmeye çalışmadan önce gönderen tarafla aynı dışlama kurallarını almasını sağlar:

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

Ancak, birleştirme dosyaları aktarımın bir parçası değilse, bazı genel hariç tutma kurallarını belirtmeniz gerekir (örn. Komut satırında belirtilir) veya dizin üzerinde kendi dizin başına birleştirme dosyalarınızı korumanız gerekir. alıcı taraf. İlki buna bir örnektir (uzak .rules dosyalarının kendilerini dışladığını varsayalım):

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

Yukarıdaki örnekte extra.rules dosyası aktarımın her iki tarafını da etkileyebilir, ancak (gönderen tarafta) kurallar, dizin başına birleştirme kuralından sonra belirtildikleri için .rules dosyalarından birleştirilen kurallara tabidir.

Son bir örnekte, uzak taraf .rsync-filtre dosyalarını aktarımdan hariç tutuyor, ancak alıcı tarafta nelerin silineceğini kontrol etmek için kendi .rsync-filtre dosyalarımızı kullanmak istiyoruz. Bunu yapmak için dizin başına birleştirme dosyalarını özellikle hariç tutmamız gerekir (böylece silinmemeleri için) ve sonra başka dosyaların silinmemesi gerekenleri kontrol etmek için yerel dosyalara kurallar koymalıyız. Bu komutlardan biri gibi:

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

0

Doğru anladıysam, --excludearadığınız şey olabilir:

$ 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

Hayır. Dışlamak istediğim tüm dosyaları el ile listelemek istemiyorum. Ben sadece kaynakta sildiğim dosyaları silmek için rsync istiyorum - ben kaynak aynı hedefe aynı dizinde diğer olası dosyaları bilmek zorunda olmamalıdır.
Heather Miller

0

Bunun için bir cevabım var. Bence işe yarıyor. Ve benim için çalışıyor. Öncelikle rsyncdosyaları yerel dosyalara uzak tutmanız gerekir . Sonra yerel tarafı tüm dosyaları içerir.

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

şimdi yerel tarafta

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

Sonra dosyaları silebilir veya istediğinizi yapabilirsiniz. (Yerel tarafta). Sorunuzda, bu dosyaları silersiniz.

silinen dosyalar

a.txt
b.txt

Bundan sonra rsyncuzak taraftaki yerel dosyaları yapabilirsiniz.O zaman her iki tarafın da aynı dosyaları vardır.

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

o verir

c.txt
d.txt
README.md

Uzak taraftaki ve yerel taraftaki dosyaları (Kullanarak --delete, uzak taraftaki yerel tarafla eşleşmeyen diğer dosyaları siler ).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.