Perché una directory copiata con il comando cp è più piccola dell'originale?


18

Sto cercando di copiare una directory con un gran numero di file in un'altra destinazione. L'ho fatto:

cp -r src_dir another_destination/

Quindi ho voluto confermare che la dimensione della directory di destinazione è la stessa di quella originale:

du -s src_dir
3782288 src_dir

du -s another_destination/src_dir
3502320 another_destination/src_dir

Poi ho pensato che potrebbero esserci diversi collegamenti simbolici che non sono seguiti dal cpcomando e ho aggiunto la -abandiera:

-a Stesse opzioni -pPR. Preserva la struttura e gli attributi dei file ma non la struttura delle directory.

cp -a src_dir another_destination/

ma du -smi ha dato gli stessi risultati. È interessante che sia l'origine che la destinazione abbiano lo stesso numero di file e directory:

tree src_dir | wc -l
    4293

tree another_destination/src_dir | wc -l
    4293

Cosa sto facendo di sbagliato nel fatto che ottengo diverse dimensioni con il ducomando?

AGGIORNARE

Quando provo ad ottenere dimensioni di singole directory con il ducomando ottengo risultati diversi:

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

Quando visualizzo i file con ls -la, le dimensioni dei singoli file sono uguali ma i totali sono diversi:

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

1
Domanda interessante. La sorgente e la destinazione sono unità diverse / Avvolgitore I se questo si riduce alla dimensione del blocco dei filesystem.
David

Ciao @davidgo, l'origine e la destinazione sono directory diverse sullo stesso disco. Ho aggiornato la domanda con i ls -larisultati. Vedi AGGIORNAMENTO
Hirurg103,

2
Quale filesystem? Forse le directory stesse sono più grandi (occupano più spazio) di quanto debbano essere. Confronta questa domanda . Le nuove directory create da cpsono esattamente grandi quanto devono essere.
Kamil Maciorowski,

Utilizzare ls -lsper visualizzare la quantità di spazio su disco utilizzata dai file.
Barmar

1
ricorsivo md5sum è tuo amico quando devi verificare che tutti i file siano effettivamente copiati e che i contenuti siano uguali. rsync è un altro strumento che può sia copiare che verificare intere strutture e file, inoltre accelera il processo se alcuni dei file sono già presenti.
GoFundMonica - codidact.org

Risposte:


21

Questo perché dudi default non mostra la dimensione dei file, ma lo spazio su disco che stanno usando. È necessario utilizzare l' -bopzione per ottenere la somma delle dimensioni del file, anziché il totale dello spazio su disco utilizzato. Per esempio:

% 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

Anche se il file è lungo solo 7 byte, occuperà 4096 byte di spazio su disco (nel mio esempio particolare; varierà a seconda del filesystem utilizzato, delle dimensioni del cluster ecc.).

Inoltre, alcuni filesystem supportano i cosiddetti file sparsi, che non usano spazio su disco per blocchi che sono tutti zeri. Per esempio:

% 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

In breve, per verificare che tutti i file siano stati copiati, dovrai utilizzare du -sbinvece di du -s.


1
non solo i file sparse , ma i file compressi e file in linea / file residenti causano anche la dimensione su disco a diventare più piccola di quelle del file
phuclv

1
E strani risultati su btrfs / zfs.
dice Val Reinstate Monica il

2
@val: la compressione BTRFS non influisce dusull'output: ciò renderebbe i file compressi poco visibili ai programmi che usano il solito algoritmo di lunghezza! = blocchi usati. btrfs.wiki.kernel.org/index.php/…
Peter Cordes il

@PeterCordes Ma le cose CoW rendono du output abbastanza insensato.
dice Val Reinstate Monica il

E i file duplicati? I sistemi moderni non possono risparmiare spazio riconoscendo il contenuto duplicato?
FreeSoftwareServers il

12

Potrebbe essere dovuto alla dimensione dei "file" della directory.

Nella maggior parte dei filesystem, su disco, una directory è molto simile a un normale file (con solo un elenco di nomi e numeri di nodo, per lo più), usando più blocchi man mano che cresce.

Se aggiungi molti file, la directory stessa cresce. Ma se li rimuovi in ​​seguito, in molti filesystem, la directory non si ridurrà.

Quindi se una delle directory nella tua struttura originale aveva molti file ad un certo punto, che sono stati successivamente eliminati, la copia di quella directory sarà "più piccola", poiché utilizza solo tutti i blocchi necessari per il numero corrente di file.

Negli elenchi del tuo aggiornamento, ci sono 3 directory che non hai elencato. Confronta le dimensioni di quelle (o discendenti di quelle) nel tuo ls -aloutput.

Per trovare la differenza, puoi provare una ls -alrsu entrambe le directory, reindirizzata a un file e quindi una diffdelle due uscite.


1
Buona cattura per un'altra possibilità! Tuttavia, nel caso dei PO cp -a src_dir another_destination/è improbabile, come another_destionationsarebbe stato creato di recente e quindi ottimizzato, mentre src_dir(che avrebbe potuto avere alcune directory più grandi dalla creazione / aggiunte passate) potrebbe effettivamente essere più grande del necessario. Tuttavia, i risultati mostrano che in src_dirrealtà è più piccolo ( 1112 < 1168).
Matija Nalis,

@MatijaNalis Solo il primo esempio dopo "Aggiornamento" mostra che (1112 <1168) ... l'esempio sotto che ha le cifre invertite, e il primo esempio mostra anche la fonte più grande (3782288 contro 3502320). Forse un errore di battitura da parte di OP?
TripeHound il

> In the listings in your update, there are 3 directories you haven't listed. In realtà sono file, non directory. vedere i nomi dei file > if one of the directories in your original tree had many files at some point, which were later deleted. Ho copiato la directory di origine da un server remoto con il comando rsync e non ho cancellato nulla da essa
Hirurg103

1
@ Hirurg103 le .voci mostrano 5 collegamenti sull'inode. Uno è il collegamento dalla directory principale a questo. Un altro è .. Ci sono altri 3 collegamenti, che dovrebbero essere ..collegamenti da sottodirectory. A meno che non mi manchi qualcosa di molto strano, ci devono essere 3 sottodirectory in quelle. Stai dicendo che quegli elenchi sono l'output completo?
jcaron,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.