ls -s 使用错误的块大小

ls -s 使用错误的块大小

乌班图Linux:LS-S不同意&统计数据为了块数由小文件使用。

ls -s  ../nc2/.git/logs/refs/heads/ 
total 4

du  ../nc2/.git/logs/refs/heads/ 
8   ../nc2/.git/logs/refs/heads/

stat ../nc2/.git/logs/refs/heads/   
File: ‘../nc2/.git/logs/refs/heads/’   
Size: 4096          Blocks: 8          IO Block: 4096 ......

sudo blockdev --getbsz /dev/sda
4096

ls -s 显示使用 4 个块的文件。 du & size 说它使用 8 个块。

为什么 ls -s 看起来是错误的?它无法检测到正确的块大小吗?我可以通过运行“ls -s --block-size 512”来表明该文件使用 8 个块。

这不是文件大小与块数量的问题。上面的所有命令都列出块大小而不是文件大小。

编辑:请求更多信息:

ls --version 
ls (GNU coreutils) 8.21

type ls  
ls is aliased to `ls --color=auto'

LS_BLOCK_SIZE=512 ls -s ../nc2/.git/logs/refs/heads/ 
total 8

答案1

ls -s报告/系统调用st_blocks返回的结构成员。这是一个 512 字节的块。 512 字节通常是最小存储粒度,因为它对应于早期磁盘扇区。stat()lstat()

或者至少这是大多数ls实现所做的事情,包括原始的 Unix 实现,以及 POSIX 所需要的。

然而,GNU 实现ls(也模仿它,两者都在 Ubuntu 上找到)将其更改为 1024 字节块,但如果(以前的)变量在环境中(不适用于 busybox),则busybox返回到 512 字节块。我认为这是为了使其更易于人类阅读,但这意味着我们会失去使用 512 字节存储粒度的文件系统的精度,并且无助于可移植性。$POSIXLY_CORRECT$POSIX_ME_HARDER

从变更日志:

1991 年 8 月 21 日星期三 13:03:14 David J. MacKenzie(djm at wookumz.gnu.ai.mit.edu)

  • 3.0版本。

  • du.c、ls.c:将 1K 块设置为默认大小,并且 -ka 无操作。打倒愚蠢的标准!

对于 GNU ls(不是 busybox),块大小也可以通过选项--block-size$LS_BLOCK_SIZE环境变量来指定。因此,您可以使用ls --block-size=1 -sLS_BLOCK_SIZE=1 ls -s来获取磁盘使用情况(以字节为单位)。其他ls实现(例如 BSD 上的实现)用于$BLOCKSIZE此功能(也$BLOCK_SIZE被 GNU认可)ls认可为由 @yahol 显示)。

POSIXly,您可以用来-k获取以千字节为单位的计数(幸运的是,GNU 或 BSDls优先于$BLOCKSIZE环境变量)。

可移植地(如果您想考虑 busybox ls,其中以千字节为单位的报告是硬编码的),要返回st_blocks(或至少是其近似值),您需要类似以下内容:

blocks=$(ls -skd -- "$file" | awk '{print $1*2; exit}')

使用 GNU find-printf %b报告许多 512 字节块和-printf %k1024 字节块,并且不受环境影响。-printf是 GNU 特定的。

无论如何,现在这与文件系统块大小无关。


1 在 BSD 上,$BLOCKSIZE四舍五入为 512 的倍数(BLOCKSIZE=1023相同BLOCKSIZE=512),并且不允许低于 512 的值

答案2

info coreutils Block size这在(我从中找到了方法)中进行了解释info ls

2.3 Block size

(...)The block size used for display is independent of
any file system block size.(...)

‘DF_BLOCK_SIZE’
     This specifies the default block size for the ‘df’ command.
     Similarly, ‘DU_BLOCK_SIZE’ specifies the default for ‘du’ and
     ‘LS_BLOCK_SIZE’ for ‘ls’.

似乎这些程序中的每一个都可以使用环境变量中定义的不同块大小。

以下两个env变量可以帮助统一输出:

‘BLOCK_SIZE’
     This specifies the default block size for all three commands, if
     the above command-specific environment variables are not set.

‘BLOCKSIZE’
     This specifies the default block size for all values that are
     normally printed as blocks, if neither ‘BLOCK_SIZE’ nor the above
     command-specific environment variables are set.  Unlike the other
     environment variables, ‘BLOCKSIZE’ does not affect values that are
     normally printed as byte counts, e.g., the file sizes contained in
     ‘ls -l’ output.

这解释了默认为 512 个块的情况:

‘POSIXLY_CORRECT’
     If neither ‘COMMAND_BLOCK_SIZE’, nor ‘BLOCK_SIZE’, nor ‘BLOCKSIZE’
     is set, but this variable is set, the block size defaults to 512.

相关内容