No está almacenado en ese archivo Se almacena en el sistema de archivos y todos los parámetros se copian manualmente uno por uno (aunque algunos no se pueden copiar en absoluto).
Es decir, la mayoría de los sistemas operativos realmente no tienen una llamada de "copiar archivo con metadatos". El programa de copia de archivos simplemente crea un nuevo archivo llamado foobar.py
, copia los 0 bytes completos de datos, luego usa utime() o SetFileTime() para hacer que su tiempo de modificación se vea igual que el original. Del mismo modo, los permisos de archivo se "copiarían" configurándolos de nuevo usando chmod() o copiando el atributo POSIX ACL.
Algunos metadatos no se copian. Establecer la propiedad requiere privilegios de raíz, por lo que las copias de los archivos de otra persona le pertenecen a usted y ocupan su cuota de disco. El ctime (tiempo de cambio de atributo) es imposible de configurar manualmente en Unixes; btime (hora de nacimiento/creación) tampoco suele copiarse.
Comparar cp -a foo bar
(que copia metadatos) y cp foo bar
(que no):
$ strace -v cp foo bar … open("foo", O_RDONLY) = 3 open("bar", O_WRONLY|O_TRUNC) = 4 read(3, "test\n", 131072) = 5 write(4, "test\n", 5) = 5 read(3, "", 131072) = 0 close(4) = 0 close(3) = 0 …
$ strace -v cp -a foo bar … -- original metadata is retrieved lstat("foo", {st_dev=makedev(254, 0), st_ino=60569468, st_mode=S_IFREG|0644, st_nlink=1, st_uid=1000, st_gid=1000, st_blksize=4096, st_blocks=8, st_size=5, st_atime=2016-12-28T09:16:59+0200.879714332, st_mtime=2016-12-28T09:16:55+0200.816363098, st_ctime=2016-12-28T09:16:55+0200.816363098}) = 0 -- data is copied open("foo", O_RDONLY|O_NOFOLLOW) = 3 open("bar", O_WRONLY|O_TRUNC) = 4 read(3, "test\n", 131072) = 5 write(4, "test\n", 5) = 5 read(3, "", 131072) = 0 -- modifiction time is copied utimensat(4, NULL, [{tv_sec=1482909419, tv_nsec=879714332}, {tv_sec=1482909415, tv_nsec=816363098}], 0) = 0 -- ownership is copied (only with 'sudo [strace] cp') fchown(4, 1000, 1000) = 0 -- extended attributes are copied (xdg.origin.url is set by browsers, wget) flistxattr(3, NULL, 0) = 0 flistxattr(3, "user.xdg.origin.url\0", 20) = 20 fgetxattr(3, "user.xdg.origin.url", "https://superuser.com/", 22) = 22 fsetxattr(4, "user.xdg.origin.url", "https://superuser.com/", 22, 0) = 0 -- POSIX ACLs are not present, so a basic ACL is built from st_mode -- (in this case, a simple fchmod() would work as well) fgetxattr(3, "system.posix_acl_access", 0x7ffc87a50be0, 132) = -1 ENODATA (No data available) fsetxattr(4, "system.posix_acl_access", "\2\0\0\0\1\0\6\0\377\377\377\377\4\0\4\0\377\377\377\377 \0\4\0\377\377\377\377", 28, 0) = 0 close(4) = 0 close(3) = 0 …
Generalmente difiere de un sistema de archivos a otro donde se almacenan los metadatos. En la familia de sistemas de archivos ext2, los metadatos que mencionó (propietario, grupo, permisos, tiempo) se almacenan en el inodo. El inodo también almacena (punteros a) los bloques que ocupa el archivo en el disco. El inodo no almacenar el nombre del archivo.
Puede acceder a estos datos con el stat
llamada al sistema (man 2 stat
), y use el stat
herramienta para imprimirlo (man stat
). Puede encontrar una descripción detallada de los campos de inodo en linux/include/linux/fs.h
en el código fuente del núcleo.
Hay otros tipos de metadatos (por ejemplo, permisos de ACL) que se almacenan en diferentes lugares.
Los metadatos no se copian de forma predeterminada cuando copia el archivo. En su lugar, se crea un nuevo archivo con valores de metadatos predeterminados. Hay varias opciones para cp
(-p
, --preserve
) que instruye a cp
para copiar también metadatos, leyendo los metadatos antiguos con stat
y modificando los nuevos metadatos en consecuencia.
Según el sistema de archivos, las áreas se reservan de forma (semi-)estática o dinámica para contener metadatos como permisos, tamaño y otros (a veces también el nombre del archivo).
En Unix, los metadatos se almacenan en el inode controlando el área de datos donde reside el archivo (mientras que los nombres de archivo y los números de inodo relacionados se almacenan en una entrada de directorio).
En algunos sistemas de archivos, las entradas de directorio son archivos como cualquier otro, pero ocultos a la vista. FAT y FAT32 son tales sistemas de archivos (aunque el directorio raíz de FAT es "especial"). Cuando crea un archivo, agrega/edita una entrada en el archivo que describe la carpeta donde reside el archivo. Cada entrada es lo suficientemente grande como para almacenar el tamaño del archivo, el nombre y la fecha, y nada más (nombres largos que ocupan varias entradas; el tamaño de entrada predeterminado de 32 bytes puede contener un solo nombre en el antiguo formato de 8+3 caracteres. Todo esto, por supuesto). , suponiendo que mi memoria esté funcionando). El sistema ext es similar, pero la entrada del directorio tiene un tamaño dinámico y contiene solo el nombre y el puntero del inodo; toda la demás información está en el inodo. De esta manera, dos entradas pueden apuntar al mismo archivo, lo cual es útil para administrar archivos duplicados.
En algunos sistemas de archivos, los inodos pueden ser lo suficientemente grandes como para contener una pequeña cantidad de datos además de los metadatos, de modo que si el archivo cabe allí, no ocupa espacio adicional en el disco. Crea un archivo de 45 bytes y el espacio libre en disco no cambia en absoluto; esos bytes se almacenan dentro el inodo. Creo que la familia ext* admite esto (y NTFS también). Esto ayuda a administrar una gran cantidad de archivos muy pequeños.
En otros sistemas de archivos, hay lo que equivale a un sistema de archivos "fantasma" junto con el principal, que almacena estos atributos adicionales. No solo la información del archivo, sino también los íconos del archivo.
Algunos sistemas tienen ambos:NTFS tiene los metadatos de directorio completos que funcionan de manera similar a un inodo y la posibilidad de crear flujos de datos alternativos contiene más información que (aparentemente) no cambia nada en el archivo "principal".