zsynchronizuj niektóre pliki, z wyjątkiem pozostałych, ignorując rekurencyjnie katalog .svn /


19

Używam rsyncdo kopiowania niektórych plików z udziału do innego.

Rekurencyjnie muszę:

  • Usuń pliki docelowe, które zostały usunięte z źródła
  • Tylko synchronizacja .phpi .jspliki
  • Wyklucz każdy inny typ pliku
  • Nie usuwaj .svn/katalogów w miejscu docelowym

Jeśli użyję tego:

rsync -zavC --delete --include='*.php' --include='*.js' --exclude="*" \
    /origin /destination

To rsyncnie jest rekurencyjne, ponieważ exclude="*"wyklucza wszystkie pliki, ale także foldery.

Jeśli dodać --include="*/"to .svn/katalog zostanie usunięty (to także dostaje w zestawie).

Jak mogę rozwiązać ten dylemat niszczenia umysłu?

uname -a:

Linux tux 3.9.2-1-ARCH # 1 SMP PREEMPT Sobota 11 maja 20:31:08 CEST 2013 x86_64 GNU / Linux

rsync wersja:

rsync 3.0.9-6

Odpowiedzi:


13

Pierwsza próba (nie zadziałała)

Oprócz plików należy dołączyć katalogi:

rsync -zavC --delete --include '*/' --include='*.php' --include='*.js' \
     --exclude="*" /media/datacod/Test/ /home/lucas/Desktop/rsync/

2. próba

rsync -avzC --filter='-rs_*/.svn*' --include="*/" --include='*.js' \
     --include='*.php' --exclude="*" --delete dir1/ dir2/

dane testowe

Napisałem ten skrypt, aby utworzyć przykładowe dane do przetestowania. Oto ten skrypt setup_svn_sample.bash:

#!/bin/bash

# setup .svn dirs
mkdir -p dir{1,2}/dir{1,2,3,4}/.svn

# fake data under .svn
mkdir -p dir1/dir{1,2,3,4}/.svn/origdir
mkdir -p dir2/dir{1,2,3,4}/.svn/keepdir

# files to not sync
touch dir1/dir{1,2,3,4}/file{1,2}

# files to sync
touch dir1/dir{1,2,3,4}/file1.js
touch dir1/dir{1,2,3,4}/file1.php

Uruchomienie go powoduje utworzenie następujących katalogów:

źródło reż

$ tree -a dir1
dir1
|-- dir1
|   |-- file1
|   |-- file1.js
|   |-- file1.php
|   |-- file2
|   `-- .svn
|       `-- origdir
|-- dir2
|   |-- file1
|   |-- file1.js
|   |-- file1.php
|   |-- file2
|   `-- .svn
|       `-- origdir
|-- dir3
|   |-- file1
|   |-- file1.js
|   |-- file1.php
|   |-- file2
|   `-- .svn
|       `-- origdir
`-- dir4
    |-- file1
    |-- file1.js
    |-- file1.php
    |-- file2
    `-- .svn
        `-- origdir

miejsce docelowe reż

$ tree -a dir2
dir2
|-- dir1
|   `-- .svn
|       `-- keepdir
|-- dir2
|   `-- .svn
|       `-- keepdir
|-- dir3
|   `-- .svn
|       `-- keepdir
`-- dir4
    `-- .svn
        `-- keepdir

Uruchomienie powyższego rsyncpolecenia:

rsync -avzC --filter='-rs_*/.svn*' --include="*/" --include='*.js' \
     --include='*.php' --exclude="*" --delete dir1/ dir2/
sending incremental file list
dir1/file1.js
dir1/file1.php
dir2/file1.js
dir2/file1.php
dir3/file1.js
dir3/file1.php
dir4/file1.js
dir4/file1.php

sent 480 bytes  received 168 bytes  1296.00 bytes/sec
total size is 0  speedup is 0.00

Wynikające z dir2 afterards:

$ tree -a dir2
dir2
|-- dir1
|   |-- file1.js
|   |-- file1.php
|   `-- .svn
|       `-- keepdir
|-- dir2
|   |-- file1.js
|   |-- file1.php
|   `-- .svn
|       `-- keepdir
|-- dir3
|   |-- file1.js
|   |-- file1.php
|   `-- .svn
|       `-- keepdir
`-- dir4
    |-- file1.js
    |-- file1.php
    `-- .svn
        `-- keepdir

Dlaczego to działa?

Kluczowym elementem tego skryptu jest wykorzystanie możliwości filtrów rsync. Filtry pozwalają usuwać pliki z dopasowanego zestawu w różnych punktach polecenia. W naszym przypadku filtrujemy wszystkie pliki pasujące do wzorca */.svn*. Modyfikatory -rs_mówią filtrowi, że chcemy filtrować zarówno po stronie źródłowej, jak i docelowej.

fragment sekcji UWAGI FILTRUJĄCE strony man rsync

  • S służy do wskazania, że zasada ta ma zastosowanie do strony wysyłającej. Gdy reguła wpływa na stronę wysyłającą, zapobiega przesyłaniu plików. Domyślnie reguła ma wpływ na obie strony, chyba że --delete-excludedokreślono inaczej , w takim przypadku reguły domyślne stają się tylko po stronie nadawcy. Zobacz także reguły ukryj (H) i pokaż (S), które są alternatywnym sposobem określania włączeń / wykluczeń po stronie wysyłającej.

  • R służy do wskazania, że zasada ta ma zastosowanie do części odbiorczej. Gdy reguła wpływa na stronę odbierającą, zapobiega usuwaniu plików. Zobacz modyfikator s, aby uzyskać więcej informacji. Zobacz także zasady ochrony (P) i ryzyka (R), które są alternatywnym sposobem określania włączeń / wyłączeń po stronie odbiornika.

Zobacz man rsync po więcej szczegółów.

Wskazówki, jak to rozwiązać (przy użyciu podpowiedzi --dry-run)

Opisując, jak to zrobić, pomyślałem, że wspomnę o --dry-runzmianie na rsync. Jest to bardzo przydatne, gdy zobaczysz, co się stanie, bez rsyncfaktycznego zajścia.

Na przykład

Użycie następującego polecenia spowoduje uruchomienie testowe i pokazanie logiki decyzyjnej rsync:

rsync --dry-run -avvzC --filter='-rs_*/.svn*' --include="*/" \
     --include='*.js' --include='*.php' --exclude="*" --delete dir1/ dir2/
sending incremental file list
[sender] showing directory dir3 because of pattern */
[sender] showing directory dir2 because of pattern */
[sender] showing directory dir4 because of pattern */
[sender] showing directory dir1 because of pattern */
[sender] hiding file dir1/file1 because of pattern *
[sender] showing file dir1/file1.js because of pattern *.js
[sender] hiding file dir1/file2 because of pattern *
[sender] showing file dir1/file1.php because of pattern *.php
[sender] hiding directory dir1/.svn because of pattern */.svn*
[sender] hiding file dir2/file1 because of pattern *
[sender] showing file dir2/file1.js because of pattern *.js
[sender] hiding file dir2/file2 because of pattern *
[sender] showing file dir2/file1.php because of pattern *.php
[sender] hiding directory dir2/.svn because of pattern */.svn*
[sender] hiding file dir3/file1 because of pattern *
[sender] showing file dir3/file1.js because of pattern *.js
[sender] hiding file dir3/file2 because of pattern *
[sender] showing file dir3/file1.php because of pattern *.php
[sender] hiding directory dir3/.svn because of pattern */.svn*
[sender] hiding file dir4/file1 because of pattern *
[sender] showing file dir4/file1.js because of pattern *.js
[sender] hiding file dir4/file2 because of pattern *
[sender] showing file dir4/file1.php because of pattern *.php
[sender] hiding directory dir4/.svn because of pattern */.svn*
delta-transmission disabled for local transfer or --whole-file
[generator] risking directory dir3 because of pattern */
[generator] risking directory dir2 because of pattern */
[generator] risking directory dir4 because of pattern */
[generator] risking directory dir1 because of pattern */
[generator] protecting directory dir1/.svn because of pattern */.svn*
dir1/file1.js
dir1/file1.php
[generator] protecting directory dir2/.svn because of pattern */.svn*
dir2/file1.js
dir2/file1.php
[generator] protecting directory dir3/.svn because of pattern */.svn*
dir3/file1.js
dir3/file1.php
[generator] protecting directory dir4/.svn because of pattern */.svn*
dir4/file1.js
dir4/file1.php
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 231 bytes  received 55 bytes  572.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

Na powyższym wyjściu widać, że ./svnkatalogi są chronione przez naszą regułę filtrowania. Cenny wgląd w debugowanie rsync.

Bibliografia


Próbowałem już tego, jak powiedziałem powyżej. Jeśli to zrobię, katalog .SVN zostanie również uwzględniony (najprawdopodobniej usunięty, ponieważ nie istnieje w źródle ani nie został zmodyfikowany). Niezwykle ważne jest pozostawienie katalogu .SVN nietkniętego. W każdym razie dzięki za próbę! :)
canolucas

-C ma zignorować „.SVN /”, ale include="*/"zawiera to
canolucas

Masz rację. Powinno być .svn, edytowanie odpowiedzi. W każdym razie po zmianie nazwy problem pozostaje. -Ci include="*/"nie wydają się być bliskimi przyjaciółmi :(
canolucas

10

Ok, po kilku próbach posortowałem to:

rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' \
    --include='*/' --exclude='*' --prune-empty-dirs \
    --filter "protect .svn/" /origin /destination

Dziękuję Ci


Świetna odpowiedź. Mój filtr chroni .svn/katalogi --prune-empty-dirsna wypadek, gdyby były puste. Inne podejście, to powielanie pustych katalogów:rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' --include='*/' --exclude='*' /origin /destination
canolucas

Kluczem mojego podejścia jest --exclude=.svn/przed --include„s
canolucas

Dobra odpowiedź również. Sugerowałbym wykluczenie = '. Svn /', ale myślałem, że chcesz użyć -C. Cieszę się, że to rozgryzłeś!
slm

0

Chociaż nie korzysta z rsync, inną opcją jest użycie find i cpio. Na przykład mam katalog o nazwie Zdjęcia i że rok i miesiąc.

Photos
├── 2002
   ├── 2002-03
      ├── 2002-03-30
      ├── 2002-03-31
      └── 2002-03-31-02
   ├── 2002-04
      ├── 2002-04-01
      ├── 2002-04-01-03
      ├── 2002-04-07
      ├── 2002-04-21
      ├── 2002-04-22
      ├── 2002-04-22-02
      └── 2002-04-27
   ├── 2002-05
      ├── 2002-05-02
      ├── 2002-05-03

Ale tutaj mam jpg, dng, xml i inne rzeczy i chcę tylko pliki jpg, więc zrobiłbym to

„cd” do katalogu nad katalogiem Zdjęcia, a następnie:

find Photos -type f -name "*jpg" -print | cpio -pdmvu /fast

I nie ma sprawy

/fast/Photos/2002/2002-04/2002-04-22/bath problem.jpg
/fast/Photos/2002/2002-04/2002-04-22-02/full bath.jpg
/fast/Photos/2002/2002-07/2002-07-10/Broken Top.jpg
/fast/Photos/2002/2002-12/2002-12-28/101-0125_IM~~G.jpg
/fast/Photos/2002/2002-12/2002-12-28/small-101-0125_IM~~G.jpg
/fast/Photos/2003/2003-01/2003-01-19/k1.jpg
/fast/Photos/2003/2003-01/2003-01-19/k2.jpg
/fast/Photos/2003/2003-02/2003-02-23/quinn.jpg
/fast/Photos/2003/2003-05/2003-05-04/all.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0015_r1.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0006_2_r1.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0006_r1.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0007_2_r1.jpg

Możesz użyć tej metody do wielu rzeczy, lata temu tak kopiowaliśmy system plików / podczas przenoszenia na większe dyski, jak kopiowałby pliki urządzeń.


To nie odpowiada na pytanie.
RalfFriedl

Dzieje się tak, jeśli użyje: find / origin -type f (-name " .php" -o -name " .js") -print | cpio -pdmvu / destination Tylko pliki * .php i * .js będą znajdować się w katalogu docelowym.
lxtwin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.