lsのファイルサイズに奇妙な違いがあります。

lsのファイルサイズに奇妙な違いがあります。

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

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

私の言葉が詰まっていますか?実際にはそれぞれ63MBと32MBなのにサイズが1MBと1MBでls -s表示されるのはなぜですか?appweb

これは、WindowsのVirtualBoxで実行されるXubuntu 14.04です。

編集する:appwebおよびファイルはすべてループで実行されるbashスクリプト(私のデザインではありません)loaderによって生成されます。dd if=/dev/urandom of=app bs=$BLOCK count=1 seek=...Cで書かれた署名プログラムはこれらのファイルをインポートし、署名されたバージョンをディスクに書き込み、各ファイルの前後にバイナリ署名を追加します。

答え1

使用している-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;
}

私が得るプログラムを実行すると、次のようになります。

$ ls -lh /tmp/foo.dat
-rw------- 1 user group 1.1G Feb  4 15:25 /tmp/foo.dat

ただし、 を使用すると、-s次のような結果が得られます。

$ ls -sh /tmp/foo.dat
4.0K /tmp/foo.dat

したがって、「hello」を保存するためにディスクに4Kブロックが割り当てられます(4Kは私のファイルシステムの最小割り当て単位です)。

あなたの場合は非常に希薄なファイルのappように見えます。web

答え2

ls -sファイルの内容が使用するストレージ容量を一覧表示します(メタデータに使用されるスペースを除く)。これは、2つの点でファイルサイズと異なる場合があります。

  • ほとんどの場合、ファイルサイズは整数ブロックに丸められます。ブロックサイズは通常512B〜4kBですが、これはファイルシステムによって異なります(一部のファイルシステムにはこの概念はありません)。
  • ファイルが圧縮などの方法でエンコードされている場合は、ファイルサイズが小さくなるか大きい場合があります。

Unixファイルシステムは、次のような粗い圧縮をサポートしています。スパースファイル: ファイルのブロックがすべて null バイトで構成されている場合は、まったく保存する必要はありません。ファイルシステムは、ファイルの内容が格納されているブロックのリストにブロック番号の代わりに特殊マークを配置します。この圧縮方法は体系的ではない。プログラムが複数のヌルバイトを書き込むと保存されます。ただし、Unixではプログラムがファイルの終わりを超えて書き込むことができます。この場合、ファイルはヌルバイトに拡張されますが、これらのバイトがブロック全体を超えて構成されている場合、そのヌルブロック全体は保存されません。

dd seek=…を書くと、ddプログラムは書き込みを始める前に与えられた位置を探します。あなたの場合、app場所はファイルの終わりから約62MBほど離れているように見えるので、存在しないブロックには約62MBのヌルバイトが暗黙的に格納されています。このリポジトリの詳細はアプリケーションに公開されていないため(非移植性インターフェイスを使用して検索することはめったにありません)、署名プログラムが入力を読み取ると約63 MBのデータしか知らないため、63 MBが出力ファイルに書き込まれます。約62MBはヌルバイトです。

ディスク容量が本当に必要な場合は、次のことができます。後でファイルをまれにする。ほとんどのファイルには大きなゼロブロックがないため、これはほとんど発生しないため、ツールを実行してそれを見つけるのに時間がかかります。

関連情報