Mengapa direktori disalin dengan perintah cp lebih kecil dari aslinya?

18

Saya ingin menyalin satu direktori dengan sejumlah besar file ke tujuan lain. Aku melakukannya:

cp -r src_dir another_destination/

Kemudian saya ingin mengkonfirmasi bahwa ukuran direktori tujuan sama dengan yang asli:

du -s src_dir
3782288 src_dir

du -s another_destination/src_dir
3502320 another_destination/src_dir

Kemudian saya berpikir bahwa mungkin ada beberapa tautan simbolis yang tidak diikuti oleh cpperintah dan menambahkan -abendera:

-a Sama seperti opsi -pPR. Mempertahankan struktur dan atribut file tetapi tidak struktur direktori.

cp -a src_dir another_destination/

tetapi du -smemberi saya hasil yang sama. Sangat menarik bahwa sumber dan tujuan memiliki jumlah file dan direktori yang sama:

tree src_dir | wc -l
    4293

tree another_destination/src_dir | wc -l
    4293

Apa yang saya lakukan salah sehingga saya mendapatkan ukuran yang berbeda dengan duperintah?

MEMPERBARUI

Ketika saya mencoba untuk mendapatkan ukuran direktori individu dengan duperintah saya mendapatkan hasil yang berbeda:

du -s src_dir/sub_dir1
1112    src_dir/sub_dir1

du -s another_destination/src_dir/sub_dir1
1168    another_destination/src_dir/sub_dir1

Ketika saya melihat file dengan ls -la, ukuran file individual adalah sama tetapi totalnya berbeda:

ls -la src_dir/sub_dir1
total 1168
drwxr-xr-x     5 hirurg103  staff     160 Jan 30 20:58 .
drwxr-xr-x  1109 hirurg103  staff   35488 Jan 30 21:43 ..
-rw-r--r--     1 hirurg103  staff  431953 Jan 30 20:58 file1.pdf
-rw-r--r--     1 hirurg103  staff  126667 Jan 30 20:54 file2.png
-rw-r--r--     1 hirurg103  staff    7386 Jan 30 20:49 file3.png

ls -la another_destination/src_dir/sub_dir1
total 1112
drwxr-xr-x     5 hirurg103  staff     160 Jan 30 20:58 .
drwxr-xr-x  1109 hirurg103  staff   35488 Jan 30 21:43 ..
-rw-r--r--     1 hirurg103  staff  431953 Jan 30 20:58 file1.pdf
-rw-r--r--     1 hirurg103  staff  126667 Jan 30 20:54 file2.png
-rw-r--r--     1 hirurg103  staff    7386 Jan 30 20:49 file3.png
Hirurg103
sumber
1
Pertanyaan menarik. Apakah sumber dan tujuan drive berbeda / I penggulung jika ini turun ke ukuran blok sistem file.
davidgo
Hai @davidgo, sumber dan tujuan adalah direktori berbeda pada drive yang sama. Saya memperbarui pertanyaan dengan ls -lahasil. Lihat PEMBARUAN
Hirurg103
2
Sistem file apa? Mungkin direktori itu sendiri lebih besar (mengambil lebih banyak ruang) daripada yang seharusnya. Bandingkan pertanyaan ini . Direktori baru yang dibuat cpsama besarnya dengan yang seharusnya.
Kamil Maciorowski
Gunakan ls -lsuntuk melihat seberapa banyak ruang disk yang digunakan file.
Barmar
1
md5sum rekursif adalah teman Anda ketika Anda perlu memverifikasi bahwa semua file benar-benar disalin dan isinya sama. rsync adalah alat lain yang dapat menyalin dan memverifikasi seluruh struktur dan file, juga mempercepat proses jika beberapa file sudah ada.
GoFundMonica - codidact.org

Jawaban:

21

Itu karena dusecara default tidak menunjukkan ukuran file, tetapi ruang disk yang mereka gunakan. Anda perlu menggunakan -bopsi untuk mendapatkan jumlah ukuran file, bukan total ruang disk yang digunakan. Sebagai contoh:

% printf test123 > a
% ls -l a
-rw-r--r-- 1 mnalis mnalis 7 Feb  1 19:57 a
% du -h a
4,0K    a
% du -hb a
7       a

Walaupun panjang file hanya 7 byte, itu akan menempati seluruh ruang disk 4096 byte (dalam contoh khusus saya; itu akan bervariasi tergantung pada sistem file yang digunakan, ukuran cluster dll).

Juga, beberapa filesystem mendukung apa yang disebut file jarang, yang tidak menggunakan ruang disk apa pun untuk blok yang semuanya nol. Sebagai contoh:

% dd if=/dev/zero of=regular.bin bs=4k count=10
10+0 records in
10+0 records out
40960 bytes (41 kB, 40 KiB) copied, 0,000131003 s, 313 MB/s
% cp --sparse=always regular.bin sparse.bin
% ls -l *.bin
-rw-r--r-- 1 mnalis mnalis 40960 Feb  1 20:04 regular.bin
-rw-r--r-- 1 mnalis mnalis 40960 Feb  1 20:04 sparse.bin
% du -h *.bin
40K     regular.bin
0       sparse.bin
% du -hb *.bin
40960   regular.bin
40960   sparse.bin

Singkatnya, untuk memverifikasi semua file telah disalin, Anda akan menggunakannya du -sbsebagai gantinya du -s.

Matija Nalis
sumber
1
tidak hanya file yang jarang tetapi file yang dikompresi dan file inline / file penduduk juga menyebabkan ukuran pada disk menjadi lebih kecil dari ukuran file
phuclv
1
Dan hasil aneh pada btrfs / zfs.
val berkata Reinstate Monica
2
@val: Kompresi BTRFS tidak mempengaruhi duoutput: yang akan membuat file terkompresi terlihat jarang untuk program yang menggunakan algoritma panjang biasa! = blok yang digunakan. btrfs.wiki.kernel.org/index.php/…
Peter Cordes
@PeterCordes Tapi hal-hal Kontrak Karya membuat du keluaran cukup tidak masuk akal.
val berkata Reinstate Monica
Bagaimana dengan file duplikat? Tidak bisakah sistem modern menghemat ruang dengan mengenali konten duplikat?
FreeSoftwareServers
12

Mungkin karena ukuran "file" direktori.

Pada sebagian besar sistem file, pada disk, direktori mirip dengan file biasa (hanya dengan daftar nama dan nomor node, sebagian besar), menggunakan lebih banyak blok seiring pertumbuhannya.

Jika Anda menambahkan banyak file, direktori itu sendiri akan tumbuh. Tetapi jika Anda menghapusnya setelah itu, di banyak filesystem, direktori tidak akan menyusut.

Jadi, jika salah satu direktori di pohon asli Anda memiliki banyak file di beberapa titik, yang kemudian dihapus, salinan direktori itu akan "lebih kecil", karena hanya menggunakan blok sebanyak yang diperlukan untuk jumlah file saat ini.

Dalam daftar di pembaruan Anda, ada 3 direktori yang belum Anda daftarkan. Bandingkan ukuran mereka (atau keturunan mereka) dalam ls -alhasil Anda .

Untuk menemukan di mana perbedaannya, Anda dapat mencoba ls -alrdi kedua direktori, diarahkan ke file, dan kemudian diffdari dua output.

jcaron
sumber
1
Tangkapan yang bagus untuk kemungkinan lain! Namun, dalam kasus OP cp -a src_dir another_destination/tidak mungkin, seperti yang another_destionationakan baru dibuat dan dengan demikian dioptimalkan, sementara src_dir(yang mungkin memiliki beberapa direktori yang lebih besar dari pembuatan / penambahan masa lalu) memang bisa lebih besar dari yang dibutuhkan. Namun hasil menunjukkan bahwa src_dirsebenarnya lebih kecil ( 1112 < 1168).
Matija Nalis
@MatijaNalis Hanya contoh pertama setelah "Pembaruan" menunjukkan bahwa (1112 <1168) ... contoh di bawah ini yang memiliki angka terbalik, dan contoh pertama juga menunjukkan sumber yang lebih besar (3782288 vs 3502320). Mungkin salah ketik oleh OP?
TripeHound
> In the listings in your update, there are 3 directories you haven't listed. Sebenarnya mereka adalah file, bukan direktori. lihat nama file > if one of the directories in your original tree had many files at some point, which were later deleted. Saya menyalin direktori sumber dari server jauh dengan perintah rsync dan tidak menghapus apa pun darinya
Hirurg103
1
@ Hirurg103 .entri menampilkan 5 tautan pada inode. Salah satunya adalah tautan dari direktori induk ke yang ini. Yang lain adalah .. Ada 3 tautan lagi, yang seharusnya berupa ..tautan dari subdirektori. Kecuali saya kehilangan sesuatu yang sangat aneh, pasti ada 3 subdirektori di dalamnya. Apakah Anda mengatakan bahwa daftar itu adalah hasil lengkap?
jcaron