bs
, the buffer size, means the size of a single read() call done by dd.
(For example, both bs=1M count=1
and bs=1k count=1k
will result in a 1 MiB file, but the first version will do it in a single step, while the second will do it in 1024 small chunks.)
Regular files can be read at nearly any buffer size (as long as that buffer fits in RAM), but devices and "virtual" files often work very close to the individual calls and have some arbitrary restriction of how much data they'll produce per read() call.
For /dev/urandom
, this limit is defined in urandom_read() in drivers/char/random.c:
#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));
...
}
This means that every time the function is called, it will clamp the requested size to 33554431 bytes.
By default, unlike most other tools, dd will not retry after receiving less data than requested – you get the 32 MiB and that's it. (To make it retry automatically, as in Kamil's answer, you'll need to specify iflag=fullblock
.)
Note also that "the size of a single read()" means that the whole buffer must fit in memory at once, so massive block sizes also correspond to massive memory usage by dd.
And it's all pointless because you usually won't gain any performance when going above ~16–32 MiB blocks – syscalls aren't the slow part here, the random number generator is.
So for simplicity, just use head -c 1G /dev/urandom > output
.
dd
at all. I'd usehead
,cat
orrsync
in its place almost always. And your question if one of the reasons why the alternatives are usually safer.head
cannot do this task without the-c
option that isn't in POSIX. I don't know any version ofcat
which can solve this.rsync
is a completely nonstandard utility. That is neither here nr there; skimming through its man page, I don't see how it can solve this problem, either./dev/urandom
isn't in POSIX either...