jun*_*ist 31 linux unix metadata
假设 Johnny 创建了一个 EMPTY 文件。它被称为foobar.py
。当 Johnny 允许执行它时,他运行chmod 755 foobar.py
. 该文件现在具有元数据
-rw-r--r-- 1 johnny staff 0 Dec 27 22:53 foobar.py
Run Code Online (Sandbox Code Playgroud)
该文件中存储的所有元数据在哪里?文件大小为0,那么当它转移到另一个驱动器时它如何保留元数据?
use*_*686 45
它没有存储在该文件中。它存储在文件系统中,所有参数都是手动一一复制的(尽管有些根本无法复制)。
也就是说,大多数操作系统实际上并没有“使用元数据复制文件”调用。文件复制程序只是创建一个名为 的新文件foobar.py
,复制整个 0 字节的数据,然后使用utime()或SetFileTime()使其修改时间看起来与原始文件相同。同样,文件权限将通过使用 chmod() 重新设置它们或通过复制 POSIX ACL 属性来“复制”。
某些元数据不会被复制。设置所有权需要 root 权限,因此其他人的文件副本属于您并占用您的磁盘配额。ctime(属性更改时间)在 Unix 上无法手动设置;btime(出生/创建时间)通常也不会被复制。
比较cp -a foo bar
(复制元数据)和cp foo bar
(不复制):
$ strace -v cp foo bar … 打开(“富”,O_RDONLY)= 3 打开(“酒吧”,O_WRONLY|O_TRUNC)= 4 读(3,“测试\n”,131072)= 5 写(4,“测试\n”,5)= 5 读(3,“”,131072)= 0 关闭(4)= 0 关闭(3)= 0 …
$ strace -v cp -a foo bar … -- 检索原始元数据 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 -- 数据被复制 open("foo", O_RDONLY|O_NOFOLLOW) = 3 打开(“酒吧”,O_WRONLY|O_TRUNC)= 4 读(3,“测试\n”,131072)= 5 写(4,“测试\n”,5)= 5 读(3,“”,131072)= 0 -- 修改时间被复制 utimensat(4, NULL, [{tv_sec=1482909419, tv_nsec=879714332}, {tv_sec=1482909415, tv_nsec=816363098}], 0) = 0 -- 所有权被复制(仅使用 'sudo [strace] cp') fchown(4, 1000, 1000) = 0 -- 复制扩展属性(xdg.origin.url 由浏览器设置,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 ACL 不存在,因此基本 ACL 是从 st_mode 构建的 --(在这种情况下,一个简单的 fchmod() 也可以工作) fgetxattr(3, "system.posix_acl_access", 0x7ffc87a50be0, 132) = -1 ENODATA (无可用数据) 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 关闭(4)= 0 关闭(3)= 0 …
dir*_*rkt 11
它通常因存储元数据的文件系统而异。在 ext2 系列文件系统上,您提到的元数据(所有者、组、权限、时间)存储在inode 中。inode 还存储(指向)文件在磁盘上占用的块。该索引节点并没有存储的文件名。
您可以使用stat
系统调用 ( man 2 stat
)访问此数据,并使用该stat
工具打印它 ( man stat
)。可以linux/include/linux/fs.h
在内核源代码中找到对 inode 字段的详细说明。
还有其他种类的元数据(例如ACL 权限)存储在不同的地方。
复制文件时默认不复制元数据。相反,会创建一个具有默认元数据值的新文件。cp
( -p
, --preserve
)有多种选项,它们指示cp
通过读取旧元数据stat
并相应地修改新元数据来复制元数据。