文件大小与 ls 的奇怪差异

neu*_*rte 3 ls size

ls -sh自 1997 年左右以来,我一直在使用检查文件大小,但今天发生了一些奇怪的事情:

ninja@vm:foo$ ls -sh
total 98M
1,0M app   
64M app_fake_signed.sbp  
800K loader  
804K loader_fake_signed.sbp  
1,0M web   
32M web_fake_signed.sbp
Run Code Online (Sandbox Code Playgroud)

appweb文件不应该比他们的同行签署的要小得多,而且我花了几个小时的调试签约程序。一无所获后,我偶然查看了 Samba 共享中的文件,发现它们的大小非常相似。我再次检查:

ninja@vm:foo$ ls -lh
total 98M
-rw-rw-r-- 1 ninja ninja  63M lut  4 14:13 app
-rw-rw-r-- 1 ninja ninja  64M lut  4 14:13 app_fake_signed.sbp
-rw-rw-r-- 1 ninja ninja 800K lut  4 14:13 loader
-rw-rw-r-- 1 ninja ninja 801K lut  4 14:13 loader_fake_signed.sbp
-rw-rw-r-- 1 ninja ninja  31M lut  4 14:13 web
-rw-rw-r-- 1 ninja ninja  32M lut  4 14:14 web_fake_signed.sbp
Run Code Online (Sandbox Code Playgroud)

我无语了?为什么ls -s显示app和 的web大小为 1MB,而实际上分别为 63MB 和 32MB?

这是在 Windows 上的 VirtualBox 中运行的 Xubuntu 14.04,如果它有什么不同的话。

编辑: 文件app,webloader都是由dd if=/dev/urandom of=app bs=$BLOCK count=1 seek=...循环运行的 bash 脚本(不是我的设计)创建的。用 C 编写的签名程序获取这些文件并将它们的签名版本写入磁盘,为每个文件添加和附加一个二进制签名。

And*_*ton 6

您正在使用-s选项ls.

文件的大小和它占用的磁盘空间量可能不同。考虑例如,如果您打开新文件,向其中查找 1G 并写入某些内容,操作系统不会在磁盘上分配 1G(加上某些空间),它只会为某些内容分配相同的空间——这称为“稀疏文件”。

我写了一个小 C 程序来创建这样一个文件:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
    int fd = open("/tmp/foo.dat", O_CREAT | O_WRONLY, 0600);

    if (fd > 0) {
        const off_t GIG = 1024 * 1024 * 1024;

        // Seek 1G into the file
        lseek(fd, GIG, SEEK_SET);

        // Write something
        write(fd, "hello", sizeof "hello");

        close(fd);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

运行该程序我得到:

$ ls -lh /tmp/foo.dat
-rw------- 1 user group 1.1G Feb  4 15:25 /tmp/foo.dat
Run Code Online (Sandbox Code Playgroud)

但是使用-s,我得到:

$ ls -sh /tmp/foo.dat
4.0K /tmp/foo.dat
Run Code Online (Sandbox Code Playgroud)

所以在磁盘上分配了一个 4K 块来存储“hello”(4K 是我的文件系统的最小分配单位)。

在你的情况下,它看起来像appweb是这样的稀疏文件。