Как я могу выполнить операцию «копировать, если изменено»?

Я хотел бы скопировать набор файлов из каталога A в каталог B с предупреждением о том, что если файл в каталоге A идентичен файлу в каталоге B, этот файл не должен копироваться (и, следовательно, время его модификации не должны обновляться). Есть ли способ сделать это с помощью существующих инструментов, не записывая свой собственный скрипт?

Чтобы немного рассказать о моем прецеденте: я создаю кучу файлов .c во временном каталоге (методом который должен генерировать все из них безоговорочно), и когда я их повторно создаю, я бы хотел скопировать только те, которые были изменены в фактический исходный каталог, оставив неизменными нетронутые (со старыми временами создания), так что make будет знать, что его не нужно перекомпилировать. (Однако не все сгенерированные файлы являются файлами .c, поэтому мне нужно выполнять бинарные сравнения, а не сравнения текста.)

(Как примечание: это выросло из вопроса, который я задал в https://stackoverflow.com/questions/8981552/speeding-up-file-comparions-with-cmp-on-cygwin/8981762#8981762 , где я пытался ускорить сценарий файл, который я использовал для выполнения этой операции, но мне кажется, что я действительно должен спросить, есть ли лучший способ сделать это, чем писать собственный скрипт, тем более, что любой простой способ сделать это в сценарии оболочки вызовет что-то вроде cmp для каждой пары файлов, и запуск всех этих процессов занимает слишком много времени.)

27 голосов | спросил Brooks Moses 24 Jam1000000amTue, 24 Jan 2012 09:15:52 +040012 2012, 09:15:52

6 ответов


27

rsync, вероятно, лучший инструмент для этого. В этой команде есть много вариантов, поэтому прочитайте справочную страницу . Я думаю, вы хотите вариант --checksum или -ignore-times

ответил Adam Terrey 24 Jam1000000amTue, 24 Jan 2012 09:47:53 +040012 2012, 09:47:53
6

Вы можете использовать переключатель -u в cp следующим образом:

$ cp -u [source] [destination]

На странице man:

   -u, --update
       copy only when the SOURCE file is newer than the destination file or 
       when the destination file is missing
ответил gu1 27 J0000006Europe/Moscow 2014, 21:26:04
4

При использовании rsync --checksum это хороший общий способ «скопировать, если он изменен», в вашем конкретном случае есть еще лучшее решение!

Если вы хотите избежать ненужной перекомпиляции файлов, вы должны использовать ccache , который был создан именно для этой цели! Фактически, он не только избежит ненужных перекомпиляций ваших автоматически сгенерированных файлов, но и ускорит работу, когда вы выполните make clean и повторно -компилировать с нуля.

Затем я уверен, что вы спросите: «Это безопасно?» Ну, да, как указывает сайт:

  

Безопасно ли это?

     

Да. Самый важный аспект кэша компилятора - всегда   производят точно такой же результат, что и настоящий компилятор.   Это включает в себя предоставление точно таких же объектных файлов и   те же предупреждения компилятора, которые будут созданы, если вы используете реальный   компилятор. Единственный способ, которым вы должны быть в состоянии сказать, что используете   ccache - скорость.

И это простой в использовании , просто добавив его в качестве префикса в ---- +: = 2 =: + ---- вашего файла makefile (или вы можете использовать символические ссылки, но способ makefile, вероятно, лучше).

ответил aculich 31 Jam1000000amTue, 31 Jan 2012 04:01:31 +040012 2012, 04:01:31
2

Это должно делать то, что вам нужно

diff -qr ./x ./y | awk '{print $2}' | xargs -n1 -J% cp % ./y/

Где:

  • x - это обновленная /новая папка
  • y - место назначения, которое вы хотите скопировать на
  • awk возьмет второй аргумент каждой строки из команды diff (возможно, вам понадобится дополнительный материал для имен файлов с пробелом - не могу попробовать сейчас)
  • xargs -J% введет имя файла в cp в нужном месте
ответил Patkos Csaba 25 Jpm1000000pmWed, 25 Jan 2012 13:29:17 +040012 2012, 13:29:17
2

Мне нравится использовать unison в пользу rsync, потому что он поддерживает несколько мастеров, имеющий уже настройте мои ssh-ключи и vpn отдельно.

Итак, в моем кронтабе только одного хоста я позволяю им синхронизировать каждые 15 минут:

  

* /15 * * * * [-z "$ (pidof unison)"] & & & (timeout 25m unison -sortbysize -ui text -batch -times /home /master ssh: //192.168.1.12//home/master -path dev -logfile   /tmp/sync.master.dev.log) & gt; /tmp/sync.master.dev.log

Тогда я могу развиваться с обеих сторон, и изменения будут распространяться. На самом деле для важных проектов у меня есть до 4 серверов, зеркалирующих одно и то же дерево (3 run unison from cron, указывающий на тот, который этого не делает). На самом деле Linux и Cygwin размещаются смешанными - за исключением того, что вы не ожидаете смысла от ссылок в win32 вне среды cygwin.

Если вы пройдете этот маршрут, сделайте исходное зеркало на пустой стороне без -batch, i.e.

unison -ui text  -times /home/master ssh://192.168.1.12//home/master -path dev

Конечно, существует возможность игнорировать файлы резервных копий, архивы и т. д .:

 ~/.unison/default.prf :
# Unison preferences file
ignore = Name {,.}*{.sh~}
ignore = Name {,.}*{.rb~}
ignore = Name {,.}*{.bak}
ignore = Name {,.}*{.tmp}
ignore = Name {,.}*{.txt~}
ignore = Name {,.}*{.pl~}
ignore = Name {.unison.}*
ignore = Name {,.}*{.zip}

    # Use this command for displaying diffs
    diff = diff -y -W 79 --suppress-common-lines

    ignore = Name *~
    ignore = Name .*~
    ignore = Path */pilot/backup/Archive_*
    ignore = Name *.o
ответил Marcos 2 FebruaryEurope/MoscowbThu, 02 Feb 2012 19:11:41 +0400000000pmThu, 02 Feb 2012 19:11:41 +040012 2012, 19:11:41
0

В то время как rsync --checksum - правильный ответ, обратите внимание, что эта опция несовместима с --times и что --archive включает --times, поэтому, если вы хотите rsync -a --checksum, вам действительно нужно rsync -a --no-times --checksum

ответил Vladimir Kornea 21 MaramSat, 21 Mar 2015 02:45:32 +03002015-03-21T02:45:32+03:0002 2015, 02:45:32

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132