Saya ingin menyalin satu set file dari direktori A ke direktori B, dengan peringatan bahwa jika file dalam direktori A identik dengan file dalam direktori B, file itu tidak boleh disalin (dan dengan demikian waktu modifikasi tidak boleh diperbarui). Apakah ada cara untuk melakukannya dengan alat yang ada, tanpa menulis skrip saya sendiri untuk melakukannya?
Untuk menguraikan sedikit kasus penggunaan saya: Saya membuat autogenerasi banyak .c
file dalam direktori sementara (dengan metode yang harus menghasilkan semuanya tanpa syarat), dan ketika saya membuat ulang, saya ingin menyalin hanya yang telah berubah menjadi direktori sumber aktual, membiarkan yang tidak berubah tidak tersentuh (dengan waktu kreasi lama mereka) sehingga make
akan tahu bahwa itu tidak perlu mengkompilasi ulang mereka. (Namun, tidak semua file yang dihasilkan adalah .c
file, jadi saya perlu melakukan perbandingan biner daripada perbandingan teks.)
(Sebagai catatan: Ini muncul dari pertanyaan yang saya ajukan di https://stackoverflow.com/questions/8981552/speeding-up-file-comparions-with-cmp-on-cygwin/8981762#8981762 , di mana saya mencoba untuk mempercepat file skrip yang saya gunakan untuk melakukan operasi ini, tetapi terpikir oleh saya bahwa saya benar-benar harus bertanya apakah ada cara yang lebih baik untuk melakukan ini daripada menulis skrip saya sendiri - terutama karena cara sederhana melakukan ini dalam shell skrip akan memanggil sesuatu seperti cmp
pada setiap pasangan file, dan memulai semua proses itu terlalu lama.)
sumber
diff -qr dirA dirB
untuk melihat file apa yang unikdirA
dandirB
, secara repektif.rsync -avnc
atau jauh-jauhrsync --archive --verbose --dry-run --checksum
.Jawaban:
rsync mungkin merupakan alat terbaik untuk ini. Ada banyak opsi pada perintah ini jadi baca halaman manual . Saya pikir Anda menginginkan opsi --checksum atau --ignore-times
sumber
-t
opsi tersebut ditentukan) atau ke waktu sinkronisasi. (jika-t
tidak ditentukan).rsync
tidak. Jika saya melakukan ini :,mkdir src dest; echo a>src/a; rsync -c src/* dest; sleep 5; touch src/a; rsync -c src/* dest
makastat dest/a
menunjukkan mtime dan ctime-nya 5 detik lebih tua dari padasrc/a
.--checksum
pilihan, dan meskipun linux.die.net/man/1/rsync sama sekali tidak mengandung apa pun yang menyiratkan bahwa ia memiliki pengaruh pada apakah tanggal modifikasi diperbarui, namun tetap menyebabkan tanggal modifikasi tujuan dibiarkan. tidak tersentuh. (Di sisi lain,--ignore-times
opsi tidak memiliki efek ini; dengan itu tanggal modifikasi masih diperbarui.) Mengingat bahwa ini tampaknya sepenuhnya tidak terdokumentasi, dapatkah saya mengandalkannya?rsync
alur kerja adalah: 1) periksa apakah file perlu diperbarui; 2) jika demikian, perbarui file. The--checksum
pilihan mengatakan itu tidak harus diperbarui, sehinggarsync
tidak harus melanjutkan ke langkah 2).--ignore-times
tanpa--checksum
akan menyalin setiap file, dan juga memperbarui timestamp, bahkan jika file tersebut identik.Anda dapat menggunakan
-u
sakelar untukcp
menyukainya:Dari halaman manual:
sumber
-u
bendera dan cara kerjanya dan bagaimana ini akan membantu OP. Namun, dalam kasus khusus ini, itu tidak akan membantu OP karena akan menyalin file yang identik jika mereka lebih baru dan karenanya mengubah perangko waktu mereka yang persis apa yang ingin OP hindari.Saat menggunakan
rsync --checksum
adalah cara umum yang baik untuk "menyalin jika diubah", dalam kasus khusus Anda ada solusi yang lebih baik!Jika Anda ingin menghindari kompilasi ulang file yang tidak perlu, Anda harus menggunakan ccache yang dibuat untuk tujuan ini! Bahkan, tidak hanya akan menghindari kompilasi ulang yang tidak perlu dari file yang Anda buat secara otomatis, itu juga akan mempercepat segala hal kapan pun Anda lakukan
make clean
dan kompilasi ulang dari awal.Selanjutnya saya yakin Anda akan bertanya, "Apakah ini aman?" Ya, seperti yang ditunjukkan situs web:
Dan mudah untuk menggunakannya hanya dengan menambahkannya sebagai awalan di
CC=
baris makefile Anda (atau Anda dapat menggunakan symlink, tetapi cara makefile mungkin lebih baik).sumber
ccache file.c -o file.o
atau setara, beberapa ratus kali karena ada beberapa ratusfile.c
file. Ketika saya melakukan itu dengancmp
, alih-alihccache
, butuh beberapa menit - dancmp
seringan ituccache
. Masalahnya adalah, pada Cygwin, memulai suatu proses membutuhkan waktu yang tidak dapat diabaikan, bahkan untuk proses yang sepenuhnya sepele.for f in src/*; do /bin/true.exe; done
butuh 30 detik, jadi ya. Lagi pula, saya lebih suka editor berbasis Windows saya, dan selain dari masalah waktu semacam ini Cygwin bekerja dengan baik dengan alur kerja saya sebagai tempat paling ringan untuk menguji berbagai hal secara lokal jika saya tidak mengunggah ke server build. Berguna memiliki shell dan editor saya di OS yang sama. :)Ini harus melakukan apa yang Anda butuhkan
Dimana:
sumber
-J
bsd-spesifik; dengan GNU xargs-I
), dan tidak berfungsi dengan benar jika set file yang sama tidak ada di kedua lokasi sudah (jika sayatouch x/boo
kemudian grep memberi sayaOnly in ./x: boo
yang menyebabkan kesalahan dalam pipa). Gunakan alat yang dibangun untuk pekerjaan itu, sepertirsync --checksum
.Saya suka menggunakan serempak yang mendukung
rsync
karena mendukung banyak master, setelah mengatur kunci ssh dan vpn saya secara terpisah.Jadi di crontab saya hanya dengan satu host saya membiarkan mereka melakukan sinkronisasi setiap 15 menit:
Lalu saya bisa berkembang di kedua sisi dan perubahan akan menyebar. Bahkan untuk proyek-proyek penting saya memiliki hingga 4 server mirroring pohon yang sama (3 jalankan berbarengan dari cron, menunjuk ke yang tidak). Bahkan, Linux dan Cygwin host dicampur - kecuali jangan berharap keluar dari tautan lunak di win32 di luar lingkungan cygwin.
Jika Anda pergi rute ini, buat cermin awal di sisi kosong tanpa
-batch
, yaituTentu saja ada konfigurasi untuk mengabaikan file cadangan, arsip, dll.:
sumber
unison
opsi yang berarti "jangan perbarui tanggal file-modifikasi terakhir". Apakah ada satu? Kalau tidak, ini adalah jawaban yang bagus untuk masalah yang sama sekali berbeda.-times
melakukan itu untukku. Unison juga memiliki mode dry-run, pikir saya.times=false
(atau meninggalkan-times
) akan melakukan itu. Saya tidak tahu bagaimana saya melewatkannya di dokumentasi sebelumnya. Terima kasih!Sementara
rsync --checksum
jawaban yang benar, perhatikan bahwa opsi ini tidak kompatibel dengan--times
, dan itu--archive
termasuk--times
, jadi jika Anda inginrsync -a --checksum
, Anda benar-benar perlursync -a --no-times --checksum
.sumber