1 GBのランダムファイルを作りたかったので、次のコマンドを使いました。
dd if=/dev/urandom of=output bs=1G count=1
しかし、代わりにこのコマンドを実行するたびに32 MBのファイルが表示されます。
<11:58:40>$ dd if=/dev/urandom of=output bs=1G count=1
0+1 records in
0+1 records out
33554431 bytes (34 MB, 32 MiB) copied, 0,288321 s, 116 MB/s
なにが問題ですか?
編集:
このトピックの素晴らしい回答のおかげで、32チャンクを32 MBの大きさにして1GBにするという解決策が生まれました。
dd if=/dev/urandom of=output bs=32M count=32
1 GBのメモリを直接読み取り、次にディスクに書き込むという解決策もあります。このソリューションは大量のメモリを消費するため、推奨されません。
dd if=/dev/urandom of=output bs=1G count=1 iflag=fullblock
バッファサイズであるbs
は、ddによって行われる単一のread()呼び出しのサイズを意味します。
(例えば、bs=1M count=1
とbs=1k count=1k
はどちらも1 MiBのファイルになりますが、最初のバージョンでは1ステップで実行され、2番目のバージョンでは1024個の小さなチャンクで実行されます。)
通常のファイルはほぼどんなバッファサイズでも(そのバッファがRAMに収まる限り)読むことができますが、デバイスと「仮想」ファイルはしばしば個々の呼び出しに非常に近く働き、それらが生成するデータ量に関して任意の制限がありますread()を呼び出します。
/dev/urandom
の場合、この制限は drivers/char/random.c のurandom_read()で定義されています。
#define ENTROPY_SHIFT 3
static ssize_t
urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
nbytes = min_t(size_t, nbytes, INT_MAX >> (ENTROPY_SHIFT + 3));
...
}
つまり、関数が呼び出されるたびに、要求されたサイズは33554431バイトに固定されます。
デフォルトでは、他のほとんどのツールとは異なり、ddは要求されたよりも少ないデータを受け取った後に再試行しません - あなたは32 MiBを得ます、それだけです。 (Kamilの答えのように自動的に再試行させるには、iflag=fullblock
を指定する必要があります。)
また、「単一のread()のサイズ」とは、バッファ全体が一度にメモリに収まる必要があることを意味します。したがって、ブロックサイズが大きいと、ddによるメモリ使用量も増えます。
16〜32 MiBブロックを超えても通常はパフォーマンスが向上しないため、これはまったく意味がありません。システムコールはここでは遅い部分ではなく、乱数ジェネレータです。
簡単にするために、単にhead -c 1G /dev/urandom > output
を使用してください。
iflag=fullblock
が指定されていない限り、dd
はibs
より少ない値で読み取ることができます(注:bs
はibs
とobs
の両方を指定します)。 0+1 records in
は、0
フルブロックおよび1
部分ブロックが読み取られたことを示します。ただし、フルブロックまたはパーシャルブロックではカウンタが増えます。
この場合、 編集: この同時回答 は、この特定のケースでdd
が1G
より小さいブロックを読み取る正確なメカニズムはわかりません。ブロックは書き込まれる前にメモリに読み込まれると思いますので、メモリ管理が妨げる可能性があります(ただしこれは推測にすぎません)。dd
が1G
より小さいブロックを読み取るメカニズムを説明しています。
とにかく、私はそのような大きなbs
をお勧めしません。私はbs=1M count=1024
を使うでしょう。最も重要なことは、iflag=fullblock
なしでは読み込み試行がibs
より少ない読み込みをするかもしれません(ibs=1
を除いて、これは非常に非効率的です)。
そのため、正確な量のデータを読み取る必要がある場合は、iflag=fullblock
を使用してください。注意iflag
はPOSIXでは必須ではありません。あなたのdd
はサポートしていないかもしれません。 によると、この回答ibs=1
はおそらく正確なバイト数を読み取る唯一のPOSIX方法です。 ibs
を変更した場合はもちろん、count
を再計算する必要があります。あなたの場合、ibs
を32M
以下に下げることはおそらくiflag=fullblock
がなくても問題を解決するでしょう。
私のKubuntuでは、私はあなたの命令をこのように修正します:
dd if=/dev/urandom of=output bs=1M count=1024 iflag=fullblock