我对 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 -l
without -s
。如果出于某种原因您已BLOCK_SIZE
设置但不想使用它,而想要ls -s
改用 1024 字节块,则传递-k
with-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
环境变量更多时候被选项覆盖。-k
overrides 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_SIZE
,ls -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_SIZE
forls -s
但不类似于ls -l
。它遵循BLOCK_SIZE
存在的情况。LS_BLOCK_SIZE
行为类似BLOCK_SIZE
,但仅影响ls
但不影响du
和df
。如果同时设置了 和 ,LS_BLOCK_SIZE
则使用 。BLOCK_SIZE
LS_BLOCK_SIZE
这些环境变量与其他变量一样,优先于POSIXLY_CORRECT
。
如上所述,请参阅第节2.3 区块大小在里面GNU coreutils 手册了解更多信息,包括这些内容的详细信息。您可以通过在命令行中输入 来阅读此手册info coreutils
,它比ls
coreutils 提供的手册页和其他命令更详细。