![文件块大小 - stat 和 ls 之间的区别](https://linux22.com/image/20320/%E6%96%87%E4%BB%B6%E5%9D%97%E5%A4%A7%E5%B0%8F%20-%20stat%20%E5%92%8C%20ls%20%E4%B9%8B%E9%97%B4%E7%9A%84%E5%8C%BA%E5%88%AB.png)
我注意到,当我执行以下操作时:
ls -ls file
它提供块计数,例如 8 个块。
当我做:
stat file
我注意到块计数是 16,是 ls 给出的数字的两倍。
我的文件系统上的块大小是 4096。我了解到 ls 使用的块的任意单位是 1024。说 stat 在报告块时使用 512 字节的任意单位是否正确?
如果是这样,是否有造成不一致的原因?
我在 ext4 文件系统上运行 Ubuntu 11.10。
答案1
许多磁盘的扇区大小为 512 字节,这意味着磁盘上的任何读取或写入一次都会传输整个 512 字节扇区。设计文件系统时,扇区不会在文件之间分割(这会使设计复杂化并损害性能),这是很自然的;因此文件系统倾向于使用 512 字节的文件块。因此,诸如ls
和 之类的传统实用程序du
以 512 字节块为单位指示大小。
对于人类来说,512字节单位意义不大。 1kB 是相同的数量级,而且更有意义。文件系统块(文件划分的最小单位)实际上通常由多个扇区组成:1kB、2kB 和 4kB 是常见的文件系统块大小;因此,文件系统设计并没有充分证明 512 字节单元是合理的,并且除了传统之外根本没有充分的理由在磁盘驱动程序之外使用 512 字节单元。
所以你有一个没有太多优势的传统,并且正在出现一个更具可读性的约定。有点像八进制和十六进制:没有正确和错误之分,它们是相同数字的不同书写方式。
许多工具都有选择显示单位的选项:ls --block-size=512
对于 GNU ,在 GNU和 GNU环境中ls
设置以获得 512 字节单位(或传递强制 1kB 单位)。 GNU coreutils 中的命令公开为“块大小”(值)的是内部接口的操作系统相关值;根据操作系统的不同,它可能与文件系统或磁盘代码使用的大小相关,也可能无关(通常不是 - 请参阅POSIXLY_CORRECT=1
df
du
-k
stat
%B
块大小和簇大小之间的差异)。在 Linux 上,无论任何底层驱动程序正在做什么,该值都是 512。的价值%B
从来不重要,它的存在只是一个怪癖。
答案2
在深入研究源代码和 POSIX 标准之后,我想说 @antje-m 和 @Gilles 的答案大部分是正确的。
值得引用的评论POSIX.1-2008,总结一下:
使用 512 字节单位是历史惯例,并且保持与 POSIX.1-2008 本卷中的 ls 和其他实用程序的兼容性。这并不要求文件系统本身基于 512 字节块。添加 -k 选项作为折衷措施。标准开发人员一致认为 512 字节是最佳默认单位,因为它在 System V 上具有完全的历史一致性(相对于 BSD 系统上的混合 512/1024 字节使用),并且 -k 选项可以切换到 1024-字节单位是一个很好的折衷方案。喜欢更逻辑的 1024 字节数量的用户可以轻松地将 df 别名为 df -k,而不会破坏许多依赖 512 字节单元的历史脚本。
对于 中的块大小ls -s
:
POSIX说默认块大小是实现定义的,除非-k
给出选项。
中实现的默认块大小GNU coreutils
ls
定义在GNU gnulib
:
gnulib/lib/human.c
/* The default block size used for output. This number may change in
the future as disks get larger. */
#ifndef DEFAULT_BLOCK_SIZE
# define DEFAULT_BLOCK_SIZE 1024
#endif
来自旧的提交:
commit 96e78d1f64d7c8d2acc5ad27dc3e73b96ae80585
Author: Jim Meyering <[email protected]>
Date: Mon Jun 29 15:23:04 1998 +0000
提交消息本身没有提及任何有关数字 1024 的内容。
du
并注意,和中使用的块大小df
也是1024,ls
只是选择与它们一致。虽然 fordu
和df
POSIX 标准有冲突(所以这里POSIXLY_CORRECT
就来了环境变量)。这似乎是 GNU 团队的决定,请参阅维基百科页面POSIX关于这个争议。
为令stat
。
它不是 POSIX 标准的一部分,但stat
系统调用是。然而,块大小的单位没有标准化(sys_stat.h):
POSIX.1-2008 中未定义 stat 结构的 st_blocks 成员的单位。
该stat
命令仅显示系统调用提供的信息stat
,并且使用 512 块大小,几乎没有例外(它们是非 Linux 的,例如 HP-UX、IBM AIX 等。请参阅 中定义的宏gnulib/lib/stat-size.h
)。
所以512这个数字更多的是历史的选择和Linux的约定。
GNU coreutils
(因此命令ls
)不是Linux内核的一部分(因此称为stat
),它们针对不同的系统方面,GNU coreutils
更适合人类(更易于阅读),而Linux内核针对硬件抽象(因此更接近硬件)。
编辑:4096块大小是“IO块”大小,真正的物理块大小可能仍然是512字节正如这个问题所解释的。
答案3
这些stat
命令使用硬盘的物理块大小。自 1956 年问世以来,基本上所有硬盘都使用 512 字节块。然而,随着高级格式的推出,这种情况最近开始发生变化。
我怀疑ls
' 1024byte-blocksize 也有历史原因。也许文件系统的块大小曾经很常见,为 1024,或者它用于为您提供以千字节为单位的大小。但是(至少对于GNU coreutils
)您可以使用选项指定块大小--block-size=
。