Я хотел создать случайный файл размером 1 ГБ, поэтому использовал следующую команду.
dd if=/dev/urandom of=output bs=1G count=1
Но вместо этого каждый раз, когда я запускаю эту команду, я получаю файл размером 32 МБ:
<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 МБ, что составляет 1 ГБ:
dd if=/dev/urandom of=output bs=32M count=32
Было дано другое решение, которое считывает 1 ГБ прямо в память, а затем записывает на диск. Это решение занимает много памяти, поэтому оно не является предпочтительным:
dd if=/dev/urandom of=output bs=1G count=1 iflag=fullblock
script
dd
random-number-generator
Трисмегиста
источник
источник
dd
вообще. Я хотел бы использоватьhead
,cat
илиrsync
на его месте почти всегда. И ваш вопрос, если одна из причин, почему альтернативы, как правило, безопаснее.head
не может выполнить эту задачу без-c
опции, отсутствующей в POSIX . Я не знаю ни одной версии,cat
которая могла бы решить эту проблему.rsync
это совершенно нестандартная утилита. Это ни здесь, ни здесь; Просматривая его справочную страницу, я тоже не вижу, как он может решить эту проблему./dev/urandom
не в POSIX либо ...Ответы:
bs
Размер буфера означает размер одиночного вызова read (), выполняемого dd.(Например, и то
bs=1M count=1
и другоеbs=1k count=1k
приведет к файлу размером 1 МБ, но первая версия сделает это за один шаг, а вторая - за 1024 маленьких фрагмента.)Обычные файлы могут быть прочитаны практически при любом размере буфера (при условии, что этот буфер помещается в ОЗУ), но устройства и «виртуальные» файлы часто работают очень близко к отдельным вызовам и имеют некоторые произвольные ограничения на объем данных, которые они будут создавать в чтение () вызов.
Для
/dev/urandom
, этот предел определен в urandom_read () в drivers / char / random.c :Это означает, что каждый раз, когда вызывается функция, она ограничивает запрошенный размер до 33554431 байта.
По умолчанию, в отличие от большинства других инструментов, dd не будет повторять попытки после получения меньшего количества данных, чем запрошено - вы получаете 32 МБ и все. (Чтобы сделать это автоматически, как в ответе Камила, вам нужно будет указать
iflag=fullblock
.)Также обратите внимание, что «размер одного read ()» означает, что весь буфер должен помещаться в памяти одновременно, поэтому огромные размеры блоков также соответствуют массовому использованию памяти dd .
И все это бессмысленно, потому что вы обычно не получаете никакой производительности, когда превышаете ~ 16–32 МБ блоков - системные вызовы здесь не медленная часть, а генератор случайных чисел.
Так что для простоты просто используйте
head -c 1G /dev/urandom > output
.источник
iflag=fullblock
это расширение GNU для утилиты POSIXdd
. Поскольку вопрос не касается Linux, я думаю, что использование специфичных для Linux расширений, вероятно, следует четко отметить, чтобы не перепутать некоторых будущих читателей, пытающихся решить аналогичную проблему в системе, отличной от Linux.dd
на моей машине, с размерами блоков от 1k до 512M. При чтении с твердотельного накопителя Intel 750 оптимальная производительность (около 1300 МБ / с) была достигнута при блоках 2 МБ, что примерно соответствует вашим результатам. Большие размеры блоков ни помогали, ни мешали. При считывании/dev/zero
оптимальная производительность (почти 20 ГБ / с) была при блоках 64 КБ и 128 КБ; и меньшие, и большие блоки снизили производительность, что примерно соответствует моему предыдущему комментарию. Итог: ориентир для вашей реальной ситуации. И, конечно же, никто из нас не тестировал/dev/random
: Pdd
, быстрее. Быстрый вывод показал, чтоhead
используется чтение 8 КБ и две записи 4 КБ, что интересно (GNU coreutils 8.26 в Debian 9.6 / Linux 4.8).head
скорости действительно где-то междуdd bs=4k
иdd bs=8k
.head
скорости снизились на ~ 40% по сравнению сdd if=/dev/zero bs=64k
и на ~ 25% по сравнению сdd if=/dev/nvme0n1 bs=2M
. Чтение из/dev/zero
, конечно, более ограничено ЦП, но для SSD очередь ввода-вывода также играет роль. Это большая разница, чем я ожидал.dd
может читать меньшеibs
(примечание:bs
указывает обаibs
иobs
), еслиiflag=fullblock
не указано иное.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 я бы исправил вашу команду следующим образом:
источник