Rsync: kopiowanie tylko znaczników czasu

42

Obecnie mam dwa katalogi A / i B /, które są identyczne pod każdym względem, z wyjątkiem znaczników czasu. Dlatego jeśli uruchomię polecenie:

rsync --dry-run -crvv A/ B/

wszystkie pliki są oznaczone jako „uptodate”, a polecenie:

rsync --dry-run -rvv A/ B/

pokazuje, że wszystkie pliki należy skopiować z A / do B /.

Moje pytanie brzmi: biorąc pod uwagę, że wiem, że pliki są identyczne (w odniesieniu do zawartości), to czy jest jakiś sposób (poprzez rsync lub w inny sposób) ustawić znaczniki czasu dla plików w B / tak, aby były identyczne z znacznikami czasu w plikach w A /, bez kopiowania wszystkich plików z A / do B /?

Dzięki

artella
źródło
Jeśli wiesz, że pliki są identyczne, to dlaczego musisz zrobić wszystko, aby nie kopiować ich w celu uzyskania wymaganego znacznika daty / godziny?
Tim
3
@Tim: może jest dużo danych.
Richard

Odpowiedzi:

75

Używanie -t(zachowaj znaczniki czasu) i --size-onlybędzie porównywać pliki tylko pod względem rozmiaru. Jeśli rozmiar się zgadza, rsync nie skopiuje pliku, ale ponieważ -tjest określony, zaktualizuje znacznik czasu w pliku docelowym bez kopiowania go.

Nie używaj -u(aktualizuj), ponieważ spowoduje to pominięcie plików, które już istnieją i całkowicie pominie aktualizację znacznika czasu.

Miałem problem z pierwotnym niestosowaniem rsync do kopiowania kilku plików na nowy dysk, dlatego znaczniki czasu zostały zaktualizowane do aktualnego czasu. Użyłem poniższego polecenia, aby zsynchronizować wszystko poprawnie w przyzwoitym czasie:

rsync -vrt --size-only /src /dest
Grant Pannell
źródło
2
Sugeruję również dodanie, --existingaby zapobiec przypadkowym kopiom nowych plików.
leden
1
Flaga --archive(lub -a) zawiera -r, -ti więcej :)
Dor
6

Użycie opcji --size-only spowoduje, że rsync pominie porównywanie znaczników czasu plików (a tym samym zawartości pliku), jeśli rozmiary są zgodne. Połączenie tego z --times sklonuje znaczniki czasu w drzewie docelowym.

użytkownik115916
źródło
3

Myślę, że rsync jest odpowiednim narzędziem do zrobienia tego, ale jeśli chcesz to zrobić, to może to dać dobry początek.

Możesz uzyskać listę plików ze znacznikami czasu (czasy dostępu) w następujący sposób:

find . -printf '"%p" %a\n' -type f > /tmp/times

I uzyskaj z niego odpowiednie polecenia aktualizacji czasu:

 while read line; do echo touch -a -d \"${line#* }\" ${line%% *}; done < /tmp/times

To nie jest kompletny skrypt, ale dobry początek! :)

Kamień
źródło
Dzięki. Myślę, że prawdopodobnie na razie pozostanę przy Rsync, ale na pewno przejdę do sieci i nauczę się różnych elementów twojego skryptu, ponieważ może to być przydatne w przyszłości.
artella
To wydawało się być dokładnie moim rozwiązaniem! Chcę zachować czas, dodając metadane do mojej biblioteki muzycznej. Jednak najwyraźniej nie obsługuje spacji w nazwach plików):
Burcardo
2

Użyj katalogu źródłowego (np. /path/to/source) Jako odniesienia do polecenia dotykowego. Po prostu cddo katalogu docelowego i zrób

find -type f -exec touch -r /path/to/source/{} {} \;

Nie możesz skopiować pod sekundowych znaczników czasu za pomocą rsync (jeszcze).

Działa to również w przypadku katalogów i pseudoplików (wystarczy usunąć lub zmienić -type f)

knorke
źródło
Było to dla mnie przydatne, ponieważ musiałem zostać skopiowany. Zauważyłem, że nie kopiuje ctime, co w moim przypadku było w porządku.
snapfractalpop
Wystarczy przeczytać stronę „dotyku”. Za pomocą tego polecenia możesz ustawić atime i mtime.
knorke
Tak, wiem, że możesz użyć, touch -arale to wciąż nie zmienia ctime. Myślę, że to rzadko pożądane.
snapfractalpop
Ach, teraz widzę problem. Dzięki. Tak, ctime trudno zmienić i nie wiem dlaczego.
knorke
1

Z pewnością możesz napisać skrypt, który odczytuje znacznik czasu z jednej strony, a następnie używa dotyku, aby ustawić go na tym samym pliku z drugiej strony.

Ale prawdopodobnie zajmie ci to znacznie więcej czasu niż zwykłe zezwolenie rsync na skopiowanie wszystkich plików. Bardzo niewiele danych zostanie faktycznie przesłanych (tylko skróty bloków, jeśli pliki są naprawdę identyczne). Ale pełna zawartość każdego pliku będzie musiała być odczytana przynajmniej z każdej strony. Więc jesteś ograniczony przepustowością dysku lub IOPS, może to chwilę potrwać. Ale nadal prawdopodobnie mniej czasu niż napisanie i przetestowanie skryptu, aby to zrobić.

rmalayter
źródło
Dzięki, nie byłem świadomy tej funkcji rsync (jest ona również omawiana na Wikipedii).
artella
0

Dla osób takich jak ja, które zamierzają zmodyfikować pliki i chcą zachować oryginalny znacznik czasu (np. Aktualizujesz metatagi biblioteki muzycznej).

Opiera się na rozwiązaniu dostarczonym przez Stone. Jednak tutaj o czasie modyfikacji i działającym skrypcie do przywracania znaczników czasu. PIERWSZE wykonaj krok pierwszy, a następnie rozpocznij pracę z plikami.

  1. Zachowaj stare znaczniki czasu . Działa z bieżącego katalogu, wyklucza wszystkie ukryte pliki i zapisuje je w pliku tymczasowym /tmp/files. Zawsze możesz zmienić parametry, ale lepiej pozostań, -printf '"%t" "%p"\n'ponieważ późniejsze touchpolecenie korzysta z tego.

    find . ! -iname ".*" -printf '"%t" "%p"\n' -type f > /tmp/files

  2. Zmodyfikuj pliki tak, jak chcesz

  3. teraz utwórz plik, który pomoże Ci przywrócić znaczniki czasu:

    while read line; do echo touch -a -d $line >> job.sh; done < /tmp/times

  4. I wreszcie zastosuj stare daty do zmodyfikowanych plików

    sh job.sh

Zastrzeżenie: działa dla plików ze spacjami, znaków specjalnych, ale na przykład nie ma plików ze $znakiem.

Burcardo
źródło
Aby uniknąć (niektórych) problemów z odwrotnymi ukośnikami w nazwach plików, użyj read -r line. Cóż, zawsze korzystać readz -r. Poza tym możesz uniknąć otwierania job.shkażdego pliku. Po prostu umieść przekierowanie na końcu polecenia:while read -r path; do echo touch -a -d $path ; done < /tmp/times > job.sh
hagello
2. zastrzeżenie: ten skrypt nie przenosi znaczników czasu do katalogów. (Cóż, OP nie poprosił o to.)
hagello
0

Najlepszy sposób na skopiowanie tylko znacznika czasu w systemie Windows:

Aby skopiować ostatnio utworzony / zmodyfikowany / uzyskany dostęp do pliku w innym pliku, możesz użyć:

dotknij / c / m / a / r SourceFile DestFile

(Ta wersja Touch jest częścią Win32 Console ToolBox http://www.stevemiller.net/apps/ )

Robocopy „SOURCE_DIRECTORY” „DESTINATION_DIRECTORY” / E / COPYALL / DCOPY: DAT / XF . / R: 10 / W: 5 / V / ETA

Pierre
źródło
-1

Podręcznik rsync: man rsyncwymienia a -ti -Nswitch, być może warto się nimi bawić.

Tim
źródło
Nie widziałem -N. Dlaczego i tak je polecasz?
Tom Hale