Intereting Posts
Почему cd не является файлом в / bin? Отключение сохранения для сеанса и сохранение в брелок по методу LXDE когда и где использовать rw, nofail, noatime, discard, defaults RAR-файл с альтернативными потоками данных как проверить, работает ли iptable правило Cron регистрирует дебианские системы Использование nohup для непрерывного выполнения сценария Сценарий Bash, создающий нежелательные файлы Выбор файловой системы для общего диска (а не файловой системы кластера, такой как GFS) жесткие диски разворачиваются процессами / приложениями, которые просто получают список дисков? Как предотвратить? Как понять, что занимает дисковое пространство? Попытка генерировать случайный проход для пользователей и сохранять их в файле Wicd запрашивает пароль при запуске Загрузите старый Ubuntu Linux после установки новой версии Linux Mint отпустите службу systemd перед выключением

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

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

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

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

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

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

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

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

Это безопасно?

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

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

Мне нравится использовать 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) &> /tmp/sync.master.dev.log

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

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

 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 

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

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

Где:

  • x – ваша обновленная / новая папка
  • y – место назначения, которое вы хотите скопировать
  • awk возьмет второй аргумент каждой строки из команды diff (возможно, вам понадобится дополнительный материал для имен файлов с пространством – не можете попробовать сейчас)
  • xargs -J% будет вставлять имя файла в cp в нужном месте

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

 $ cp -u [source] [destination] 

На странице руководства:

  -u, --update copy only when the SOURCE file is newer than the destination file or when the destination file is missing 

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