统计

统计

我对 Ubuntu 还很陌生,想学习更多 Linux 编程。

每次我打印ls -l并再次比较st_blocks每个文件中添加的我自己的代码时,结果总是统计块是ls块大小的两倍?

对此有什么特别的解释吗?


在命令行中:

$ ls -ls
total 28
4 ... test
20 ... test.c
4 ... test.txt

用于对非‘.’文件求和的程序:

$ myls
total 56
8 ... test
40 ... test.c
8 ... test.txt

循环中使用的代码摘录:

...
    ...
        if (dirName[0] != '.') {
            blocksize += buf.st_blocks;
    }
    return blocksize;
...

答案1

统计

在使用 Linux 内核的系统(包括所有 GNU/Linux 系统,例如 Ubuntu)上,用作单位的块大小st_blocks始终为 512 字节。在大多数其他类 Unix 操作系统上,它的大小也是这个。

作为Stephen Kitt 解释道在他的回答中为什么 st_blocks 总是以 512 字节块的形式报告?

块的大小是特定于实现的。在 Linux 上,由于历史原因,块的大小始终为 512 字节;具体来说,它曾经是磁盘扇区的典型大小

(重点是我的)

统计(2)列出了 的成员struct stat,其中包括:

blkcnt_t  st_blocks;      /* number of 512B blocks allocated */

stat命令(参见统计(1)) 同样使用 512 字节块大小。例如,正如 所示ls -l,在我的系统上/bin/nano大小为 208480 字节,并且 的输出stat /bin/nano包括Blocks: 408


ls

ls -l默认情况下以字节为单位打印文件大小,但ls -s以 1024 字节块为单位打印。ls某些类 Unix 系统的实现默认为 512 字节块,但 GNU ls(/bin/ls在 Ubuntu 中提供)和busybox ls(Ubuntu 中的另一个ls实现)都默认为 1024 字节块。您不需要通过-k此行为,即使在其他一些系统上可能需要这样做。

当以块为单位打印文件大小时,Ubuntu 的ls命令默认为 1024 字节块,因为这样更方便。您可以根据--block-size需要更改此设置。在实践中,我认为最流行的方法是:

  • 传递-l而不-s获取字节大小(实际上是块大小为 1)
  • 通过-l-s使用-h单位标签打印更多可读的尺寸
  • 传递-s并使用默认值 1024 字节

一些 GNU 实用程序在运行时打印 512 字节块POSIX 兼容模式.du是一个特别明显的例子;将 的输出du /bin/nano与 的输出进行比较。当传递POSIXLY_CORRECT= du /bin/nano时,GNU ls 也会以这种方式运行,但带有和不带有 的输出以及带有 的输出均不受影响。(没有选项的输出当然也不受影响,因为它不会打印大小。)-s-l-s-h

除了支持 之外--block-size,GNU ls 还尊重其他一些环境变量,最值得注意的是BLOCK_SIZE。与 不同POSIXLY_CORRECT,这不仅会影响ls -s,还会影响ls -lwithout -s。如果出于某种原因您已BLOCK_SIZE设置但不想使用它,而想要ls -s改用 1024 字节块,则传递-kwith-s将覆盖它。

还有其他方法可以调整这一点,当同时使用多种方法时,会涉及一些微妙之处。有关快速详细信息,请参阅下面的示例和ls(1)man ls)。如需了解详细信息,请阅读GNU coreutils 手册(也应该在本地可用:运行info coreutils),尤其是部分2.3 区块大小


ls例子

下面是一些控制 显示的单位大小的示例ls

ls -l打印字节大小:

$ ls -l /bin/nano
-rwxr-xr-x 1 root root 208480 Feb 15  2017 /bin/nano

ls -s以 1024 字节块为单位打印大小:

$ ls -s /bin/nano
204 /bin/nano

添加-h到以人类可读的形式打印它:

$ ls -lh /bin/nano
-rwxr-xr-x 1 root root 204K Feb 15  2017 /bin/nano
$ ls -sh /bin/nano
204K /bin/nano

传递-l和会将自身显示的-s内容添加到前面-s,而不会影响生成的列的大小-l

$ ls -ls /bin/nano
204 -rwxr-xr-x 1 root root 208480 Feb 15  2017 /bin/nano
$ ls -lsh /bin/nano
204K -rwxr-xr-x 1 root root 204K Feb 15  2017 /bin/nano

-k在上面显示的命令中添加-s-l不会改变输出,因为 GNU ls 已经默认使用 来显示 2014 字节块-s,并且-l以字节为单位显示大小,并且不受 的影响-k。但是,-k在更复杂的情况下会产生影响(见下文)。

添加会导致以指定大小的块形式打印尺寸:--block-size=size-in-bytes

$ ls --block-size=256 -s /bin/nano
816 /bin/nano
$ ls --block-size=512 -s /bin/nano
408 /bin/nano
$ ls --block-size=1024 -s /bin/nano
204 /bin/nano

与其他一些选项不同,该选项甚至对通常以字节为单位显示--block-size的大小列也具有这种影响:ls -l

$ ls --block-size=256 -l /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano
$ ls --block-size=512 -l /bin/nano
-rwxr-xr-x 1 root root 408 Feb 15  2017 /bin/nano
$ ls --block-size=1024 -l /bin/nano
-rwxr-xr-x 1 root root 204 Feb 15  2017 /bin/nano
$ ls -l /bin/nano
-rwxr-xr-x 1 root root 208480 Feb 15  2017 /bin/nano

--block-size不是被 覆盖-k,即使-k在其后出现:

$ ls -s --block-size=256 -k /bin/nano
816 /bin/nano
$ ls -s -k --block-size=256 /bin/nano
816 /bin/nano
$ ls -l --block-size=256 -k /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano
$ ls -l -k --block-size=256 /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano

(我的例子使用了 2 的幂,但是操作数--block-size不必是 2 的幂。而且,-s-l显然使用了不同的舍入规则。)

设置BLOCK_SIZE环境变量与传递以下内容具有类似的效果--block-size

$ BLOCK_SIZE=256 ls -s /bin/nano
816 /bin/nano
$ BLOCK_SIZE=512 ls -s /bin/nano
408 /bin/nano
$ BLOCK_SIZE=1024 ls -s /bin/nano
204 /bin/nano
$ BLOCK_SIZE=256 ls -l /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano
$ BLOCK_SIZE=512 ls -l /bin/nano
-rwxr-xr-x 1 root root 408 Feb 15  2017 /bin/nano
$ BLOCK_SIZE=1024 ls -l /bin/nano
-rwxr-xr-x 1 root root 204 Feb 15  2017 /bin/nano

--block-size选项和 环境变量之间的效果差异BLOCK_SIZE在于,BLOCK_SIZE环境变量更多时候被选项覆盖。-koverrides BLOCK_SIZE

$ BLOCK_SIZE=256 ls -k -s /bin/nano
204 /bin/nano

这与 兼容-s。但-k不会覆盖BLOCK_SIZE所显示的尺寸-l,因为(如上所述)-k不会影响 :

$ BLOCK_SIZE=256 ls -k -l /bin/nano
-rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano
$ BLOCK_SIZE=256 ls -kls /bin/nano
204 -rwxr-xr-x 1 root root 815 Feb 15  2017 /bin/nano

--block-size还会覆盖BLOCK_SIZE。由于--block-size会影响-s-l,因此它会覆盖BLOCK_SIZE两者:

$ BLOCK_SIZE=256 ls --block-size=512 -s /bin/nano
408 /bin/nano
$ BLOCK_SIZE=256 ls --block-size=512 -l /bin/nano
-rwxr-xr-x 1 root root 408 Feb 15  2017 /bin/nano
$ BLOCK_SIZE=256 ls --block-size=512 -ls /bin/nano
408 -rwxr-xr-x 1 root root 408 Feb 15  2017 /bin/nano

设置POSIXLY_CORRECT环境变量,即使将其设置为空字符串,也会导致ls -s使用 512 字节块。-h-k--block-size选项会覆盖此效果,而是产生其指定的行为。但与--block-size和不同BLOCK_SIZEls -l仍然以字节为单位打印大小。

$ POSIXLY_CORRECT= ls -s /bin/nano
408 /bin/nano
$ POSIXLY_CORRECT= ls -sh /bin/nano
204K /bin/nano
$ POSIXLY_CORRECT= ls -sk /bin/nano
204 /bin/nano
$ POSIXLY_CORRECT= ls --block-size=256 -s /bin/nano
816 /bin/nano
$ POSIXLY_CORRECT= ls -l /bin/nano
-rwxr-xr-x 1 root root 208480 Feb 15  2017 /bin/nano

BLOCK_SIZE优先于POSIXLY_CORRECT

$ BLOCK_SIZE=256 POSIXLY_CORRECT= ls -s /bin/nano
816 /bin/nano

影响块大小的选项当然也优先于POSIXLY_CORRECT,因为POSIXLY_CORRECT只是更改默认块大小。特别是,-k覆盖POSIXLY_CORRECT

$ POSIXLY_CORRECT= ls -s /bin/nano
408 /bin/nano
$ POSIXLY_CORRECT= ls -sk /bin/nano
204 /bin/nano

ls- 其他选择

我没有展示所有相关选项和环境变量的组合。

此外,还有两个环境变量与 GNU ls 如何选择块大小有关:

  • BLOCKSIZE(请注意,没有下划线)的行为类似于BLOCK_SIZEforls -s但不类似于ls -l。它遵循BLOCK_SIZE存在的情况。
  • LS_BLOCK_SIZE行为类似BLOCK_SIZE,但仅影响ls但不影响dudf。如果同时设置了 和 ,LS_BLOCK_SIZE则使用 。BLOCK_SIZELS_BLOCK_SIZE

这些环境变量与其他变量一样,优先于POSIXLY_CORRECT

如上所述,请参阅第节2.3 区块大小在里面GNU coreutils 手册了解更多信息,包括这些内容的详细信息。您可以通过在命令行中输入 来阅读此手册info coreutils,它比lscoreutils 提供的手册页和其他命令更详细。

相关内容