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)
在app
和web
文件不应该比他们的同行签署的要小得多,而且我花了几个小时的调试签约程序。一无所获后,我偶然查看了 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
,web
和loader
都是由dd if=/dev/urandom of=app bs=$BLOCK count=1 seek=...
循环运行的 bash 脚本(不是我的设计)创建的。用 C 编写的签名程序获取这些文件并将它们的签名版本写入磁盘,为每个文件添加和附加一个二进制签名。
您正在使用-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 是我的文件系统的最小分配单位)。
在你的情况下,它看起来像app
和web
是这样的稀疏文件。