Yalnızca belirli bir dosya listesini nasıl yeniden senkronize edebilirim?


95

Uzak bir sunucuya göndermek istediğim çeşitli alt dizinlerde yaklaşık 50 dosyam var. Rsync'in bunu --include-from seçeneğini kullanarak yapabileceğini düşündüm. --Exclude = "*" seçeneği olmadan, dizindeki tüm dosyalar, seçenekle senkronize edilir, hiçbir dosya senkronize edilmez.

rsync -avP -e ssh --include-from=deploy/rsync_include.txt --exclude=* ./ root@0.0.0.0:/var/www/ --dry-run

Başlangıçta kuru olarak çalıştırıyorum ve 0.0.0.0 açıkça uzak sunucunun IP'si ile değiştirildi. Rsync_include.txt içeriği, yüklemek istediğim dosyalara giden göreceli yolların satırla ayrılmış yeni bir listesidir.

Bunu yapmanın daha iyi bir yolu pazartesi sabahı benden kaçıyor mu?

Yanıtlar:


4

Düzenleme: Josip Rodin'in aşağıdaki cevabı daha iyi. Lütfen bunu kullanın!

Belirli bir dosya listesi arıyorsanız, bunları doğrudan komut satırına koyarak daha kolay zaman geçirebilirsiniz:

# rsync -avP -e ssh `cat deploy/rsync_include.txt` root@0.0.0.0:/var/www/

Ancak bu, listenizin komut satırı uzunluğunun bir sorun oluşturacak kadar uzun olmadığı ve rsync_include.txtdosyanın sadece gerçek yollar içerdiğini (yani yorum ve regexps içermediğini) varsayar.


9
Maalesef bu, büyük bir liste veya adında boşluklar bulunan dosyalarda çalışmaz.
Wes Modes

3
[Bağımsız değişken listesi çok uzun]
Dankó Dávid

Varsayılan olarak, xargs argümanları stdin'den komut satırının sonuna ekler. Bu, rsync'in hedef olmak için son argümana ihtiyacı olduğu için çalışmaz. Bazı xargs sürümleri isteğe bağlı olarak argümanları komut satırının ortasına ekleyebilir. Bu, dosya listesi uzun olduğunda rsync'i bir kereden fazla çalıştırabileceğini düşünmediğiniz sürece çalışmalıdır. Her durumda, rsync --files-frommuhtemelen daha kolay ve daha güvenilir bir çözümdür :)
Lassi

Wes Hardaker: Düzenlemeniz ve "Josip Rodin'in cevabına" referansınız aslında Rodin'in düzenlediği @atp cevabına mı atıfta bulunuyor ?
Seamus

234

--files-fromTam olarak istediğinizi yapan bir bayrak var. Kimden man rsync:

--files-from=FILE

Bu seçeneğin kullanılması, aktarılacak dosyaların tam listesini belirlemenize olanak tanır (belirtilen DOSYA'dan okunduğu gibi veya - standart giriş için). Ayrıca, yalnızca belirtilen dosya ve dizinlerin aktarılmasını kolaylaştırmak için rsync'in varsayılan davranışını da değiştirir:

  • Dosyadaki her öğe için belirtilen yol bilgisini koruyan --relative (-R) seçeneği belirtilir (kapatmak istiyorsanız --no-relative veya --no-R kullanın).

  • Listede belirtilen dizinleri gürültülü bir şekilde atlamak yerine yaratacak olan --dirs (-d) seçeneği belirtilmiştir (kapatmak istiyorsanız --no-dirs veya --no-d kullanın).

  • --Archive (-a) seçeneğinin davranışı --recursive (-r) anlamına gelmez, bu nedenle, isterseniz bunu açıkça belirtin.

  • Bu yan etkiler rsync'in varsayılan durumunu değiştirir, bu nedenle komut satırındaki --files-from seçeneğinin konumunun diğer seçeneklerin nasıl ayrıştırıldığıyla ilgisi yoktur (örn. -A, --files- öncesinde veya sonrasında aynı şekilde çalışır- --no-R ve diğer tüm seçenekler gibi).

DOSYA'dan okunan dosya adlarının tümü kaynak dizine göredir - baştaki eğik çizgiler kaldırılır ve ".." referanslarının kaynak dizininden daha yükseğe çıkmasına izin verilmez. Örneğin, şu komutu alın:

rsync -a --files-from=/tmp/foo /usr remote:/backup

/ Tmp / foo "bin" (hatta "/ bin") dizesini içeriyorsa, / usr / bin dizini uzak ana bilgisayarda / backup / bin olarak oluşturulacaktır. "Bin /" içeriyorsa (sondaki eğik çizgiye dikkat edin), dizinin hemen içeriği de gönderilir (dosyada açıkça belirtilmesine gerek kalmadan - bu sürüm 2.6.4'te başlamıştır). Her iki durumda da, -r seçeneği etkinleştirilirse, o dizinin tüm hiyerarşisi de aktarılır (-a ile ima edilmediğinden -r'nin --files-from ile açıkça belirtilmesi gerektiğini unutmayın). Ayrıca (varsayılan olarak etkindir) --relative seçeneğinin etkisinin, yalnızca dosyadan okunan yol bilgisini çoğaltmak olduğunu unutmayın - kaynak özellik yolunun (bu durumda / usr) çoğaltılmasını zorlamaz. .

Ayrıca --files-from dosyası, dosyanın önünde bir "ana bilgisayar:" belirtirseniz yerel ana bilgisayar yerine uzak ana bilgisayardan okunabilir (ana bilgisayar aktarımın bir ucuyla eşleşmelidir). Kısayol olarak, "aktarımın uzak ucunu kullan" anlamına gelmek üzere yalnızca ":" önekini belirtebilirsiniz. Örneğin:

rsync -a --files-from=:/path/file-list src:/ /tmp/copy

Bu, uzak "src" ana bilgisayarında bulunan / path / file-list dosyasında belirtilen tüm dosyaları kopyalar.

--İconv ve --protect-args seçenekleri belirtilirse ve --files-from dosya adları bir ana bilgisayardan diğerine gönderiliyorsa, dosya adları gönderen ana bilgisayarın karakter kümesinden alan ana bilgisayarın karakter kümesine çevrilir.

NOT: --files-from girdisindeki dosyaların listesinin sıralanması, bitişik girdiler arasında paylaşılan yol öğelerinin yeniden ziyaret edilmesini önleyeceği için rsync'in daha verimli olmasına yardımcı olur. Girdi sıralanmamışsa, bazı yol öğeleri (ima edilen dizinler) birden çok kez taranabilir ve rsync sonunda dosya listesi öğelerine dönüştürüldükten sonra bunları tekilleştirecektir.


23
Halen listelenen dosyaların bulunduğu dizini belirtmeniz gerektiğini unutmayın, örneğin: rsync -av --files-from=file-list . target/dosyaları geçerli dizinden kopyalamak için.
Nicolas Mattia

7
Evet ve reiterate için: The filenames that are read from the FILE are all relative to the source dir.
atp

Ah, bunu kaçırdım, üzgünüm!
Nicolas Mattia

1
dosyadan-dosyasında ..rsync ile başlayan herhangi bir şey varsa, ..bana benzer bir hata vermeyi görmezden geliyor gibi görünür rsync: link_stat "/home/michael/test/subdir/test.txt" failed: No such file or directory(bu durumda "test" dizininden çalıştırılıyor ve var olan "../subdir/test.txt" yi belirtmeye çalışıyor.
Michael

Bağımsız --files-fromdeğişken, açık bir içerme ve dışlama listesiyle birleştirilebilir mi ve listedeki dosyalar, --files-frommevcut dışlama kurallarını geçersiz kılar, böylece dosyada görünürlerse dahil edilirler mi?
highsciguy

13

--files-from=Mutlak yolu olduğu gibi tutmak istiyorsanız parametresinin sonunda bölü çizgisi olması gerekir. Yani emriniz aşağıdaki gibi olacaktır:

rsync -av --files-from=/path/to/file / /tmp/

Bu, çok sayıda dosya olduğu ve tüm dosyaları x yoluna kopyalamak istediğiniz gibi yapılabilir. Böylece dosyaları bulur ve çıktıyı aşağıdaki gibi bir dosyaya atarsınız:

find /var/* -name *.log > file

9

Kayıt için, yukarıdaki cevaplardan biri dışında hiçbiri yardımcı olmadı. Özetlemek gerekirse, aşağıdakilerden --files-from=birini kullanarak yedekleme işlemini yapabilirsiniz :

 rsync -aSvuc `cat rsync-src-files` / mnt / d / rsync_test /

VEYA

rsync -aSvuc --recursive --files-from = rsync-src-files. / mnt / d / rsync_test /

İlk komut, rsync-src-filesaşağıda detaylandıracağım dosyanın içeriğinin yanı sıra kendi kendini açıklayıcıdır . Şimdi, ikinci sürümü kullanmak istiyorsanız, aşağıdaki dört açıklamayı aklınızda bulundurmanız gerekir:

  1. İkisini de --files-fromve kaynak dizini belirtmek gerektiğine dikkat edin
  2. Açıkça belirtilmesi gerekiyor --recursive.
  3. Dosya rsync-src-files, kullanıcı tarafından oluşturulan bir dosyadır ve bu test için src dizinine yerleştirilmiştir
  4. rsyn-src-filesKopya dosyaları ve klasörleri içeren ve bunlar kaynak dizinine göreli alınır. ÖNEMLİ: Dosyanın sonunda boşluklar veya boş satırlar olmadığından emin olun. Aşağıdaki örnekte, üç değil yalnızca iki çizgi vardır (Şans eseri bulun). İçeriği rsynch-src-files:

klasörAdı1
klasörAdı2


3

Benzer bir görev aldım: belirli bir tarihten sonra değiştirilen tüm dosyaları yeniden senkronize etmek, ancak bazı dizinleri hariç tutmak. Tek astarlı hepsi bir arada stil oluşturmak zordu, bu yüzden problemi daha küçük parçalara ayırdım. Son çözüm:

find  ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | egrep -v "/\..|Downloads|FOO" > FileList.txt
rsync -v --files-from=FileList.txt ~/sourceDIR /Destination

İlk önce kullanıyorum find -L ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS". Ad kalıplarını hariç tutmak regexiçin findsatıra eklemeye çalıştım , ancak benim Linux (Mint) tarzım, normal ifadeyi olumsuzlamayı anlamamak için ekliyor find. Denenen normal ifade çeşidi sayısı - istenildiği gibi çalışmaz. Bu yüzden egrep -v- desen kolay yolunu dışlayan seçenekle sonuçlandım . Benim rsyncgibi dizinleri kopyalama değildir /.cache veya /.config artı açıkça adlandırılmış diğer bazı I.


1
Bunu bashtek rsync -v --files-from=<(find ~/sourceDIR -type f -newermt "DD MMM YYYY HH:MM:SS" | grep -Ev "/\..|Downloads|FOO") ~/sourceDIR /Destination
satırlık

2
$ date
  Wed 24 Apr 2019 09:54:53 AM PDT
$ rsync --version
  rsync  version 3.1.3  protocol version 31
  ...

Sözdizimi: rsync <file_/_folder_list> <source> <target>

Klasör adları (burada, sonda İLE /; örn. Cancer - Evolution/) Bir klasör listesi dosyasındadır (örneğin: cm_folder_list_test):

# /mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test
# test file: 2019-04-24
Cancer/
Cancer - Evolution/
Cancer - Genomic Variants/
Cancer - Metastasis (EMT Transition ...)/
Cancer Pathways, Networks/
Catabolism - Autophagy; Phagosomes; Mitophagy/
Catabolism - Lysosomes/

Bu /sonları eklemezseniz, rsync'de hedef klasörler oluşturulur, ancak boştur.

Bu klasör adları yollarının geri kalanına ( /home/victoria/Mail/2_RESEARCH - NEWS) eklenir , böylece rsync'e tam klasör yolu sağlanır; örneğin: /home/victoria/Mail/2_RESEARCH - NEWS/Cancer - Evolution/.

Ayrıca şunu kullanmanız gerektiğini de unutmayın --files-from=..., DEĞİL --include-from=...

rsync -aqP --delete --files-from=/mnt/Vancouver/projects/ie/claws/data/cm_folder_list_test "/home/victoria/Mail/2_RESEARCH - NEWS" $IN/

(BASH betiğimde değişkeni $INaşağıdaki gibi tanımladım .)

BASEDIR="/mnt/Vancouver/projects/ie/claws"
IN=$BASEDIR/data/test/input

kullanılan rsync seçenekleri:

 -a  :   archive: equals -rlptgoD (no -H,-A,-X)
    -r  :   recursive
    -l  :   copy symlinks as symlinks
    -p  :   preserve permissions
    -t  :   preserve modification times 
    -g  :   preserve group 
    -o  :   preserve owner (super-user only) 
    -D  :   same as --devices --specials 
  -q  :   quiet (/server/547106/run-totally-silent-rsync)

  --delete
    This  tells  rsync to delete extraneous files from the RECEIVING SIDE (ones
    that AREN’T ON THE SENDING SIDE), but only for the directories that are
    being synchronized.  You must have asked rsync to send the whole directory
    (e.g.  "dir" or "dir/") without using a wildcard for the directory’s contents
    (e.g. "dir/*") since the wildcard is expanded by the shell and rsync thus
    gets a request to transfer individual files, not the files’ parent directory.
    Files  that  are  excluded  from  the transfer are also excluded from being
    deleted unless you use the --delete-excluded option or mark the rules as
    only matching on the sending side (see the include/exclude modifiers in the
    FILTER RULES section).  ...

1

Bu cevap, sorunun doğrudan cevabı değildir. Ancak, sorununuz için hangi çözümün en uygun olduğunu belirlemenize yardımcı olacaktır.

Sorunu analiz ederken hata ayıklama seçeneğini etkinleştirmelisiniz -vv

Daha sonra rsync hangi dosyaların hangi kalıp tarafından dahil edildiğini veya hariç tutulduğunu çıkarır:

building file list ... 
[sender] hiding file FILE1 because of pattern FILE1*
[sender] showing file FILE2 because of pattern *

0

Sahip olduğum tek şey bir dizin listesiyken , bu yanıtların hiçbiri benim için işe yaramadı . Sonra çözüme rastladım! Sen eklemek zorunda -riçin --files-fromçünkü -abu senaryo (kim biliyordu ?!) içinde özyinelemeli olmayacaktır.

rsync -aruRP --files-from=directory.list . ../new/location

Dosyada “dir” listelerseniz, -r / —recursive; "dir /" listelerseniz, yapmazsınız.
lbutlr
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.