ディレクトリAからディレクトリBに一連のファイルをコピーしたいと思います。ただし、ディレクトリAのファイルがディレクトリBのファイルと同一である場合、そのファイルはコピーしないでください(そのため、変更時間は更新しました)。独自のスクリプトを作成せずに、既存のツールでそれを行う方法はありますか?
ユースケースについて少し詳しく説明します。一時ディレクトリに一連の.c
ファイルを自動生成しています(無条件にすべてを生成する必要がある方法で)。ファイルを再生成すると、 d変更されたもののみを実際のソースディレクトリにコピーし、変更されていないものは(古い作成時刻で)そのままにして、make
が再コンパイルする必要がないことを認識できるようにします。 (ただし、生成されたすべてのファイルが.c
ファイルではないため、テキスト比較ではなくバイナリ比較を行う必要があります。)
(メモとして:これは私が尋ねた質問から生まれました https://stackoverflow.com/questions/8981552/speeding-up-file-comparions-with-cmp-on-cygwin/8981762#8981762 、この操作を実行するために使用していたスクリプトファイルを高速化しようとしていましたが、これを行うには、独自のスクリプトを作成するよりも優れた方法があるかどうかを本当に質問する必要があります。シェルスクリプトでこれを行う方法では、ファイルのすべてのペアでcmp
のようなものが呼び出され、それらすべてのプロセスの開始には時間がかかります。)
rsyncはおそらくこれに最適なツールです。このコマンドにはたくさんのオプションがあるので、 man page を読んでください。 --checksumオプションまたは--ignore-timesが必要だと思います
-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
rsync --checksum
を使用することは、「変更された場合にコピーする」ための優れた一般的な方法ですが、特定のケースではさらに優れた解決策があります。
不必要にファイルを再コンパイルしないようにするには、この目的のために作成された ccache を使用する必要があります。実際、自動生成されたファイルの不必要な再コンパイルを回避するだけでなく、make clean
を実行して最初から再コンパイルするたびにスピードアップします。
次に、きっと「安全ですか?」と尋ねるでしょう。まあ、はい、ウェブサイトが指摘するように:
安全ですか?
はい。コンパイラー・キャッシュの最も重要な側面は、実際のコンパイラーが生成するものとまったく同じ出力を常に生成することです。これには、実際のコンパイラを使用した場合に生成されるまったく同じオブジェクトファイルとまったく同じコンパイラ警告が含まれます。 ccacheを使用していることを確認できる唯一の方法は、速度です。
そして、それは 使いやすい メイクファイルのCC=
行に接頭辞として追加するだけです(またはシンボリックリンクを使用できますが、メイクファイルの方法がおそらくより優れています)。
これはあなたが必要なことをするはずです
diff -qr ./x ./y | awk '{print $2}' | xargs -n1 -J% cp % ./y/
どこ:
私はnisonを使用してrsync
を優先して使用します。これは、複数のマスターをサポートし、sshキーとVPNを個別に設定しているためです。
したがって、1つのホストのみのcrontabで、15分ごとに同期させます。
*/15 * * * * [-z "$(pidof unison)"] &&(タイムアウト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つはcronからunisonを実行し、そうでないサーバーを指します)。実際、LinuxとCygwinのホストは混在しています。ただし、cygwin環境外のwin32のソフトリンクから意味を期待しないでください。
このルートを使用する場合は、-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
rsync --checksum
が正解ですが、このオプションは--times
と互換性がなく、--archive
には--times
が含まれるため、rsync -a --checksum
を使用する場合は、本当にrsync -a --no-times --checksum
が必要です。