¿Por qué se copia un directorio con el comando cp más pequeño que el original?

18

Estoy tratando de copiar un directorio con una gran cantidad de archivos a otro destino. Yo hice:

cp -r src_dir another_destination/

Entonces quería confirmar que el tamaño del directorio de destino es el mismo que el original:

du -s src_dir
3782288 src_dir

du -s another_destination/src_dir
3502320 another_destination/src_dir

Luego pensé que podría haber varios enlaces simbólicos que no fueran seguidos por el cpcomando y agregué la -abandera:

-a Igual que las opciones -pPR. Conserva la estructura y los atributos de los archivos, pero no la estructura del directorio.

cp -a src_dir another_destination/

pero du -sme dio los mismos resultados. Es interesante que tanto el origen como el destino tengan la misma cantidad de archivos y directorios:

tree src_dir | wc -l
    4293

tree another_destination/src_dir | wc -l
    4293

¿Qué estoy haciendo mal que obtengo diferentes tamaños con el ducomando?

ACTUALIZAR

Cuando intento obtener tamaños de directorios individuales con el ducomando obtengo 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

Cuando veo archivos con ls -la, los tamaños de archivo individuales son los mismos pero los totales son 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
fuente
1
Interesante pregunta. ¿Las unidades de origen y destino son diferentes? Me pregunto si esto se reduce al tamaño de bloque de los sistemas de archivos.
David
Hola @davidgo, el origen y el destino son directorios diferentes en la misma unidad. Actualicé la pregunta con ls -laresultados. Ver ACTUALIZACIÓN
Hirurg103
2
¿Qué sistema de archivos? Es posible que los directorios en sí sean más grandes (ocupen más espacio) de lo necesario. Compara esta pregunta . Los nuevos directorios creados por cpson exactamente tan grandes como deben ser.
Kamil Maciorowski
Use ls -lspara ver cuánto espacio en disco están usando los archivos.
Barmar
1
md5sum recursivo es tu amigo cuando necesitas verificar que todos los archivos estén copiados y que el contenido sea el mismo. rsync es otra herramienta que puede copiar y verificar estructuras y archivos completos, también acelera el proceso si algunos de los archivos ya están en su lugar.
GoFundMonica - codidact.org

Respuestas:

21

Esto se debe a que, dude manera predeterminada, no muestra el tamaño de los archivos, sino el espacio en disco que están utilizando. Debe usar la -bopción para obtener la suma de los tamaños de archivo, en lugar del total del espacio en disco utilizado. Por ejemplo:

% 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

Aunque el archivo tiene solo 7 bytes de longitud, ocupará un total de 4096 bytes de espacio en disco (en mi ejemplo particular; variará según el sistema de archivos utilizado, el tamaño del clúster, etc.).

Además, algunos sistemas de archivos admiten los llamados archivos dispersos, que no utilizan ningún espacio en disco para bloques que son todos ceros. Por ejemplo:

% 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

En resumen, para verificar que todos los archivos fueron copiados, usaría en du -sblugar de du -s.

Matija Nalis
fuente
1
no solo los archivos dispersos sino también los archivos comprimidos y los archivos en línea / residentes también hacen que el tamaño del disco sea más pequeño que el tamaño del archivo
phuclv
1
Y resultados extraños en btrfs / zfs.
Val dice reinstalar a Mónica
2
@val: la compresión BTRFS no afecta la dusalida: eso haría que los archivos comprimidos se vean dispersos para los programas que usan el algoritmo habitual de longitud! = bloques usados. btrfs.wiki.kernel.org/index.php/…
Peter Cordes
@PeterCordes Pero las cosas de CoW hacen que la salida no tenga mucho sentido.
Val dice reinstalar a Mónica
¿Qué pasa con los archivos duplicados? ¿No pueden los sistemas modernos ahorrar espacio al reconocer contenido duplicado?
FreeSoftwareServers
12

Puede deberse al tamaño del directorio "archivos".

En la mayoría de los sistemas de archivos, en el disco, un directorio es muy parecido a un archivo normal (con solo una lista de nombres y números de nodo, en su mayoría), utilizando más bloques a medida que crece.

Si agrega muchos archivos, el directorio en sí crece. Pero si luego los elimina, en muchos sistemas de archivos, el directorio no se reducirá.

Entonces, si uno de los directorios de su árbol original tenía muchos archivos en algún momento, que luego se eliminaron, la copia de ese directorio será "más pequeña", ya que solo usa tantos bloques como sea necesario para la cantidad actual de archivos.

En los listados de su actualización, hay 3 directorios que no ha enumerado. Compare el tamaño de esos (o descendientes de esos) en su ls -alsalida.

Para encontrar la diferencia, puede probar un ls -alren ambos directorios, redirigido a un archivo y luego una diffde las dos salidas.

jcaron
fuente
1
Buena captura para otra posibilidad! Sin embargo, en el caso de los OP cp -a src_dir another_destination/, es poco probable, ya another_destionationque se crearía nuevamente y, por lo tanto, se optimizaría, mientras src_dirque (que podría haber tenido algunos directorios más grandes de creaciones / adiciones anteriores) podría ser más grande de lo necesario. Sin embargo, los resultados muestran que en src_dirrealidad es más pequeño ( 1112 < 1168).
Matija Nalis
@MatijaNalis Solo el primer ejemplo después de "Actualizar" muestra que (1112 <1168) ... el siguiente ejemplo tiene las cifras invertidas, y el primer ejemplo también muestra la fuente más grande (3782288 frente a 3502320). ¿Posiblemente un error tipográfico de OP?
TripeHound
> In the listings in your update, there are 3 directories you haven't listed. En realidad son archivos, no directorios. ver los nombres de los archivos > if one of the directories in your original tree had many files at some point, which were later deleted. Copié el directorio fuente de un servidor remoto con el comando rsync y no
eliminé
1
@ Hirurg103 las .entradas muestran 5 enlaces en el inodo. Uno es el enlace del directorio principal a este. Otro es .. Hay 3 enlaces más, que deberían ser ..enlaces de subdirectorios. A menos que me falte algo muy extraño, debe haber 3 subdirectorios en ellos. ¿Estás diciendo que esos listados son la salida completa?
jcaron