Почему rsync пытается скопировать файл, который уже обновлен?

24

У меня есть два одинаковых файла, на локальной машине и на удаленной. Их размеры равны, и файл на локальном компьютере новее, чем на удаленном, но rsync все еще пытается скопировать файл.

Я вызываю rsync следующим образом:

rsync -nv -e "ssh -p 2222" user@host:/data/file.fif data/file.fif

(если я не использую -nопцию, она инициирует операцию копирования)

Документы Rsync прямо заявляют, что это не должно происходить:

Rsync  finds files that need to be transferred using a "quick check" algorithm (by default) that looks for files that have changed in size or in last-modified time.

Выходы из stat:

# remote file
  File: `data/fif/Skovorodko_Olga_45_raw.fif'
  Size: 1137551966  Blocks: 2221784    IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 286338      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1037/  platon)   Gid: ( 1047/  platon)
Access: 2013-08-08 18:40:16.907581658 +0400
Modify: 2013-07-16 12:01:09.158763284 +0400
Change: 2013-07-16 12:01:09.158763284 +0400

# local file
  File: `data/fif/Skovorodko_Olga_45_raw.fif'
  Size: 1137551966  Blocks: 2221792    IO Block: 4096   regular file
Device: 801h/2049d  Inode: 12987232    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1005/  platon)   Gid: ( 1003/  platon)
Access: 2013-08-08 19:02:57.146223369 +0400
Modify: 2013-08-08 19:02:57.146223369 +0400
Change: 2013-08-08 19:02:57.146223369 +0400

Почему это происходит?

ОБНОВИТЬ:

Делать rsync --size-onlyфайл результатов не копируется:

delta-transmission enabled
Skovorodko_Olga_45_raw.fif is uptodate
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 14 bytes  received 114 bytes  85.33 bytes/sec
total size is 1137551966  speedup is 8887124.73 (DRY RUN)
Рогач
источник

Ответы:

37

Алгоритм быстрой проверки будет считать измененным любой файл, который имеет другое время модификации или другой размер. Таким образом, если в вашем каталоге назначения установлена ​​более новая версия того же файла, он будет считаться другим и будет синхронизирован с исходной версией.

Это ожидаемое (и безопасное) поведение. Например, предположим, у вас есть две директории, ~ / src и ~ / dest, каждая из которых имеет файл foobar. В ~ / src / foobar вы пишете "foo", а затем в ~ / dest / foobar вы пишете "bar". Теперь вы rsync ~ / src в ~ / dest. Чего бы вы ожидали?

Оба файла имеют одинаковый размер, но файл в ~ / dest новее. Стандартное поведение Rsync - заменить ~ / dest / foobar на ~ / src / foobar. Конечно, файлы могут быть идентичными, и это будет излишним, но нет никакого способа узнать это, если вы не сделаете контрольную сумму или сравните бит за битом.

Если вы не хотите такого поведения, то есть хотите, чтобы новые файлы в приемнике были сохранены, вы должны использовать флаг -u (--update).

-u, --update Это заставляет rsync пропускать любые файлы, которые существуют в месте назначения и имеют измененное время, которое является более новым, чем исходный файл. (Если существующий конечный файл имеет время модификации, равное времени исходного файла, оно будет обновлено, если размеры будут другими.)

Рафаэль Кавальканти
источник
2
Да, это была действительно проблема. Я забыл добавить -tфлаг, чтобы он не устанавливал правильное время изменения нового файла, и последующие вызовы rsync пытались обновить более новый файл. Благодарность!
Рогач
13
@Rogach Всегда используйте, rsync -aесли у вас нет веских причин не делать этого.
Жиль "ТАК - перестань быть злым"
Я получал ту же проблему с OP, но -aв этом случае это привело бы к другой проблеме, а именно к ошибке skipping directory .. Причина была в том, что -aсодержит, -rи я думаю, что если в папке не было никаких каталогов, это выдает эту ошибку. Обсуждается в этом сообщении
кардамон
@cardamom По-прежнему следует использовать -aпо умолчанию, а затем явно отключить любой параметр, который он включает, который вам не нужен, с --no-префиксом. В вашем случае это было бы rsync -a --no-r.
Уолф