Czy mogę użyć rsync do utworzenia listy tylko zmienionych plików?

26

Korzystam z rsync w skrypcie bash, aby synchronizować pliki między kilkoma serwerami i serwerem NAS. Jednym z problemów, na jakie natknąłem się, jest próba wygenerowania listy plików, które zmieniły się w trakcie rsync.

Chodzi o to, że kiedy uruchamiam rsync, mogę wysyłać pliki, które zmieniły się w plik tekstowy - bardziej licząc na tablicę w pamięci - wtedy zanim skrypt będzie istniał, mogę uruchomić chown tylko na zmienionych plikach.

Czy ktoś znalazł sposób na wykonanie takiego zadania?

# specify the source directory
source_directory=/Users/jason/Desktop/source

# specify the destination directory
# DO NOT ADD THE SAME DIRECTORY NAME AS RSYNC WILL CREATE IT FOR YOU
destination_directory=/Users/jason/Desktop/destination

# run the rsync command
rsync -avz $source_directory $destination_directory

# grab the changed items and save to an array or temp file?

# loop through and chown each changed file
for changed_item in "${changed_items[@]}"
do
        # chown the file owner and notify the user
        chown -R user:usergroup; echo '!! changed the user and group for:' $changed_item
done
Jason M.
źródło
→ zobacz moją odpowiedź tutaj . Również -idla wyszczególnienia, ale z kilkoma dodatkowymi
zwrotami

Odpowiedzi:

42

Możesz użyć opcji rsync --itemize-changes( -i) do wygenerowania analizowalnego wyniku, który wygląda następująco:

~ $ rsync src/ dest/ -ai
.d..t.... ./
>f+++++++ newfile
>f..t.... oldfile

~ $ echo 'new stuff' > src/newfile

~ $ !rsync
rsync src/ dest/ -ai
>f.st.... newfile

>Postać na pierwszym miejscu wskazuje, że plik został zaktualizowany, pozostałe znaki wskazują, dlaczego, na przykład tutaj si twskazują, że rozmiar pliku i timestamp zmieniło.

Szybkim i brudnym sposobem uzyskania listy plików może być:

rsync -ai src/ dest/ | egrep '^>'

Oczywiście bardziej zaawansowane parsowanie może zapewnić czystszy wynik :-)

Natrafiłem na ten świetny link, próbując dowiedzieć się, kiedy --itemize-changeszostał wprowadzony, bardzo przydatny:

http://andreafrancia.it/2010/03/understanding-the-output-of-rsync-itemize-changes.html (link zarchiwizowany)

Kyle Smith
źródło
2
Dla czystszego wyjścia, jak wspomniano, wyświetlałbym rsync -zaic src/ dest/ | grep '^?c' | cut -d' ' -f2 --dry-runtylko zmodyfikowane pliki ( inną sumę kontrolną ), zdecydowanie opiekun, dziękuję :) FYI wstawianie --dry-runpolecenia zamiast korzystania z nopcji jest dla mnie najlepszą praktyką
MediaVince
Zasadniczo taki sam, jak rsync -zavc src/ dest/ --dry-runbez gadatliwy
MediaVince
14

Użyj -nflagi w połączeniu z -cflagą sumy kontrolnej i -iflagą:

# rsync -naic test/ test-clone/
>fcst...... a.txt
>fcst...... abcde.txt
>fcst...... b.txt

W tym przykładzie zmienił się tylko jeden plik, w zależności od zawartości samego pliku. Jednak synchronizacja plików nie jest wykonywana z powodu -nflagi

Premia

Jeśli chcesz uruchomić chown na zmienionych plikach, przeanalizuj je za pomocą sedlub podobnie i przetworz za pomocą xargs, na przykład:

rsync -naic test/ test-clone/ | sed 's/............//' | xargs -I+ sudo chown root "test-clone/+"
JDS
źródło
3
sed->cut -d ' ' -f2,-
MUY Belgia,
-n --dry-run, -c --checksum,-i --itemize-changes
ThorSummoner
Nie śledzę. Wszystkie 3 pliki w tym przykładzie są oznaczone jako „> fcst”, co, jak rozumiem, oznacza „otrzymanie ze zdalnego”, suma kontrolna różni się, rozmiar różni się, czas różni się. Co w danych wyjściowych wskazuje, że „zmienił się tylko jeden plik”?
bobpaul
1

To pytanie jest trochę stare, ale myślę, że warto je dodać:

-i jest skrótem od --out-format=%i%n%L

I %nśrodki nazwa pliku (odcinek log formatod man rsyncd.conf)

PS rsync wersja 3.1.0

Cychih
źródło
W rzeczywistości w tej odpowiedzi wspomniano o tej opcji
Cychih