Por que um diretório copiado com o comando cp é menor que o original?

18

Estou tentando copiar um diretório com um grande número de arquivos para outro destino. Eu fiz:

cp -r src_dir another_destination/

Então eu queria confirmar que o tamanho do diretório de destino é o mesmo que o original:

du -s src_dir
3782288 src_dir

du -s another_destination/src_dir
3502320 another_destination/src_dir

Pensei que houvesse vários links simbólicos que não fossem seguidos pelo cpcomando e adicionei a -aflag:

-a Mesmo que as opções -pPR. Preserva a estrutura e os atributos dos arquivos, mas não a estrutura de diretórios.

cp -a src_dir another_destination/

mas du -sme deu os mesmos resultados. É interessante que a origem e o destino tenham o mesmo número de arquivos e diretórios:

tree src_dir | wc -l
    4293

tree another_destination/src_dir | wc -l
    4293

O que estou fazendo de errado em obter tamanhos diferentes com o ducomando?

ATUALIZAR

Quando tento obter tamanhos de diretórios individuais com o ducomando, obtenho resultados diferentes:

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 visualizo arquivos com ls -la, os tamanhos de arquivos individuais são os mesmos, mas os totais são diferentes:

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
fonte
1
Pergunta interessante. A origem e o destino são diferentes unidades / enrolador se isso se resumir ao tamanho do bloco dos sistemas de arquivos.
davidgo 01/02
Olá @davidgo, a origem e o destino são diretórios diferentes na mesma unidade. Eu atualizei a pergunta com ls -laresultados. Veja UPDATE
Hirurg103
2
Qual sistema de arquivos? Pode ser que os próprios diretórios sejam maiores (ocupam mais espaço) do que precisam. Compare esta pergunta . Os novos diretórios criados por cpsão exatamente tão grandes quanto precisam.
Kamil Maciorowski
Use ls -lspara ver quanto espaço em disco os arquivos estão usando.
Barmar 01/02
1
O md5sum recursivo é seu amigo quando você precisa verificar se todos os arquivos foram realmente copiados e o conteúdo é o mesmo. O rsync é outra ferramenta que pode copiar e verificar estruturas e arquivos inteiros, além de acelerar o processo se alguns dos arquivos já estiverem no local.
GoFundMonica - codidact.org

Respostas:

21

Isso ocorre porque, dupor padrão, mostra não o tamanho do (s) arquivo (s), mas o espaço em disco que eles estão usando. Você precisa usar a -bopção para obter a soma dos tamanhos dos arquivos, em vez do total do espaço em disco usado. Por exemplo:

% 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

Mesmo que o arquivo tenha apenas 7 bytes de comprimento, ele ocupará um total de 4096 bytes de espaço em disco (no meu exemplo particular; variará dependendo do sistema de arquivos usado, do tamanho do cluster etc.).

Além disso, alguns sistemas de arquivos oferecem suporte aos chamados arquivos esparsos, que não usam espaço em disco para blocos que são todos zeros. Por exemplo:

% 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

Em resumo, para verificar se todos os arquivos foram copiados, você usaria em du -sbvez de du -s.

Matija Nalis
fonte
1
não apenas arquivos esparsos, mas arquivos compactados e arquivos embutidos / arquivos residentes também fazem com que o tamanho do disco fique menor que o tamanho do arquivo
phuclv 02/02
1
E resultados estranhos em btrfs / zfs.
val diz Reinstate Monica
2
@val: a compactação BTRFS não afeta a dusaída: isso faria com que os arquivos compactados parecessem escassos para os programas que usam o algoritmo usual de comprimento! = used blocks. btrfs.wiki.kernel.org/index.php/…
Peter Cordes
@ PeterCordes Mas o material CoW torna a saída bastante sem sentido.
val diz Reinstate Monica
E os arquivos duplicados? Os sistemas modernos não podem economizar espaço reconhecendo conteúdo duplicado?
FreeSoftwareServers
12

Pode ser devido ao tamanho do diretório "arquivos".

Na maioria dos sistemas de arquivos, em disco, um diretório é muito parecido com um arquivo comum (com apenas uma lista de nomes e números de nós, principalmente), usando mais blocos à medida que cresce.

Se você adicionar muitos arquivos, o próprio diretório aumentará. Mas se você os remover posteriormente, em muitos sistemas de arquivos, o diretório não diminuirá.

Portanto, se um dos diretórios da sua árvore original tiver muitos arquivos em algum momento, que foram posteriormente excluídos, a cópia desse diretório será "menor", pois usa apenas quantos blocos forem necessários para o número atual de arquivos.

Nas listagens da sua atualização, existem 3 diretórios que você não listou. Compare o tamanho desses (ou descendentes deles) em sua ls -alsaída.

Para descobrir onde está a diferença, tente um ls -alrnos dois diretórios, redirecionado para um arquivo e, em seguida, uma diffdas duas saídas.

jcaron
fonte
1
Boa captura para outra possibilidade! No entanto, no caso de OPs cp -a src_dir another_destination/, é improvável, pois another_destionationseria recém-criado e, portanto, otimizado, enquanto src_dir(que pode ter alguns diretórios maiores de criações / adições anteriores) poderia realmente ser maior do que o necessário. No entanto, os resultados mostram que src_diré realmente menor ( 1112 < 1168).
Matija Nalis 02/02
@MatijaNalis Somente o primeiro exemplo após a "Atualização" mostra que (1112 <1168) ... o exemplo abaixo que tem os números revertidos e o primeiro exemplo também mostra a fonte maior (3782288 vs. 3502320). Possivelmente um erro de digitação por OP?
TripeHound
> In the listings in your update, there are 3 directories you haven't listed. Na verdade, eles são arquivos, não diretórios. veja os nomes dos arquivos > if one of the directories in your original tree had many files at some point, which were later deleted. Copiei o diretório de origem de um servidor remoto com o comando rsync e não excluí nada dele
Hirurg103 02/02
1
@ Hirurg103 as .entradas mostram 5 links no inode. Um é o link do diretório pai para este. Outro é .. Existem mais 3 links, que devem ser ..links de subdiretórios. A menos que esteja faltando algo muito estranho, deve haver três subdiretórios nesses. Você está dizendo que essas listagens são a saída completa?
jcaron 02/02