Program md5sum tidak menyediakan checksum untuk direktori. Saya ingin mendapatkan satu checksum MD5 untuk seluruh isi direktori, termasuk file di sub-direktori. Artinya, satu checksum gabungan yang dibuat dari semua file. Apakah ada cara untuk melakukan ini?
Jawaban yang Diterima:
Cara yang benar bergantung pada alasan Anda bertanya:
Opsi 1:Bandingkan Data Saja
Jika Anda hanya membutuhkan hash dari konten file pohon, ini akan berhasil:
$ find -s somedir -type f -exec md5sum {} ; | md5sum
Ini pertama-tama merangkum semua konten file satu per satu, dalam urutan yang dapat diprediksi, lalu meneruskan daftar nama file dan hash MD5 untuk di-hash itu sendiri, memberikan nilai tunggal yang hanya berubah ketika konten salah satu file di pohon berubah.
Sayangnya, find -s
hanya bekerja dengan BSD find(1), digunakan di macOS, FreeBSD, NetBSD dan OpenBSD. Untuk mendapatkan sesuatu yang sebanding pada sistem dengan GNU atau SUS find(1), Anda memerlukan sesuatu yang sedikit lebih buruk:
$ find somedir -type f -exec md5sum {} ; | sort -k 2 | md5sum
Kami telah meniru perilaku BSD find -s
dengan menambahkan panggilan ke sort
. -k 2
bit memberitahunya untuk melewati hash MD5, jadi itu hanya mengurutkan nama file, yang ada di bidang 2 hingga akhir baris dengan sort
perhitungan.
Ada kelemahan dengan versi perintah ini, yaitu kemungkinan menjadi bingung jika Anda memiliki nama file dengan baris baru di dalamnya, karena akan terlihat seperti beberapa baris ke sort
panggilan. find -s
varian tidak memiliki masalah itu, karena traversal dan pengurutan pohon terjadi dalam program yang sama, find
.
Dalam kedua kasus tersebut, penyortiran diperlukan untuk menghindari kesalahan positif:sistem file Unix/Linux yang paling umum tidak mempertahankan daftar direktori dalam urutan yang stabil dan dapat diprediksi. Anda mungkin tidak menyadari hal ini dengan menggunakan ls
dan semacamnya, yang secara diam-diam mengurutkan konten direktori untuk Anda. Memanggil find
tanpa mengurutkan outputnya dalam beberapa cara akan menyebabkan urutan baris dalam output cocok dengan urutan apa pun yang dikembalikan oleh sistem file yang mendasarinya, yang akan menyebabkan perintah ini memberikan nilai hash yang diubah jika urutan file yang diberikan padanya sebagai input berubah, bahkan jika data tetap sama.
Anda mungkin bertanya apakah -k 2
bit di GNU sort
perintah di atas diperlukan. Mengingat bahwa hash dari data file adalah proxy yang memadai untuk nama file selama isinya tidak berubah, kita tidak akan mendapatkan kesalahan positif jika kita menjatuhkan opsi ini, memungkinkan kita untuk menggunakan perintah yang sama dengan GNU dan BSD sort
. Namun, sadarilah bahwa ada kemungkinan kecil (1:2 dengan MD5) bahwa urutan nama file yang tepat tidak sesuai dengan urutan parsial yang dilakukan tanpa -k 2
dapat memberikan jika pernah ada tabrakan hash. Namun, perlu diingat, jika kemungkinan kecil dari ketidakcocokan seperti itu penting bagi aplikasi Anda, seluruh pendekatan ini mungkin tidak cocok untuk Anda.
Anda mungkin perlu mengubah md5sum
perintah ke md5
atau fungsi hash lainnya. Jika Anda memilih fungsi hash lain dan memerlukan bentuk kedua dari perintah untuk sistem Anda, Anda mungkin perlu menyesuaikan sort
perintah sesuai. Perangkap lain adalah bahwa beberapa program penjumlahan data tidak menuliskan nama file sama sekali, contoh utama adalah sum
Unix yang lama. program.
Metode ini agak tidak efisien, memanggil md5sum
N+1 kali, di mana N adalah jumlah file di pohon, tetapi itu adalah biaya yang diperlukan untuk menghindari hashing metadata file dan direktori.
Opsi 2:Bandingkan Data dan Metadata
Jika Anda harus dapat mendeteksi apa pun itu di pohon telah berubah, bukan hanya konten file, tanyakan tar
untuk mengemas isi direktori untuk Anda, lalu kirimkan ke md5sum
:
$ tar -cf - somedir | md5sum
Karena tar
juga melihat izin file, kepemilikan, dll., ini juga akan mendeteksi perubahan pada hal-hal tersebut, bukan hanya perubahan pada konten file.
Metode ini jauh lebih cepat, karena hanya membuat satu kali melewati pohon dan menjalankan program hash hanya sekali.
Seperti halnya find
berdasarkan metode di atas, tar
akan memproses nama file dalam urutan yang dikembalikan oleh sistem file yang mendasarinya. Mungkin saja dalam aplikasi Anda, Anda dapat yakin bahwa Anda tidak akan menyebabkan hal ini terjadi. Saya dapat memikirkan setidaknya tiga pola penggunaan yang berbeda di mana hal itu mungkin terjadi. (Saya tidak akan mencantumkannya, karena kita masuk ke wilayah perilaku yang tidak ditentukan. Setiap sistem file bisa berbeda di sini, bahkan dari satu versi OS ke versi berikutnya.)
Jika Anda mendapati diri Anda mendapatkan hasil positif palsu, saya sarankan untuk menggunakan find | cpio
pilihan dalam jawaban Gilles.