Я создаю 1 ТБ файл со случайными данными с dd if=/dev/urandom of=file bs=1M count=1000000
. Теперь я проверяю kill -SIGUSR1 <PID>
прогресс и получаю следующее:
691581+0 Datensätze ein
691580+0 Datensätze aus
725174190080 Bytes (725 GB) kopiert, 86256,9 s, 8,4 MB/s
800950+1 Datensätze ein
800950+0 Datensätze aus
839856947200 Bytes (840 GB) kopiert, 99429,5 s, 8,4 MB/s
dd: warning: partial read (809620 bytes); suggest iflag=fullblock
803432+1 Datensätze ein
803431+1 Datensätze aus
842459273876 Bytes (842 GB) kopiert, 99791,3 s, 8,4 MB/s
Я не могу интерпретировать предупреждение. Что это говорит? Мой файл действительно случайный после предупреждения или есть проблема? Что +0 или +1 в 800950+1 Datensätze ein
и 800950+0 Datensätze aus
средний? После предупреждения это +1. Это ошибка?
LC_ALL=C
перед командой, например,LC_ALL=C dd if=...
Ответы:
Резюме:
dd
капризный инструмент, который трудно использовать правильно. Не используйте его, несмотря на многочисленные уроки, которые говорят вам об этом.dd
к нему прикреплена атмосфера «Unix Street Credit» - но если вы действительно понимаете, что делаете, вы будете знать, что вам не следует прикасаться к нему 10-футовым шестом.dd
совершает один вызовread
системного вызова на блок (определяется значениемbs
). Нет гарантии, чтоread
системный вызов вернет столько данных, сколько указано в размере буфера. Это работает для обычных файлов и блочных устройств, но не для каналов и некоторых символьных устройств. См. Когда dd подходит для копирования данных? (или, когда read () и write () частично) для получения дополнительной информации. Еслиread
системный вызов возвращает менее одного полного блока, тоdd
передается частичный блок. Он по-прежнему копирует указанное количество блоков, поэтому общее количество переданных байтов меньше запрашиваемого.Предупреждение о «частичном чтении» говорит вам именно об этом: одно из чтений было частичным, поэтому
dd
передан неполный блок. В подсчете блоков+1
означает, что один блок был прочитан частично; так как количество выводов равно+0
, все блоки были записаны как прочитанные.Это не влияет на случайность данных: все
dd
записываемые байты являются байтами, из которых они считывают/dev/urandom
. Но вы получили меньше байтов, чем ожидалось.Linux принимает
/dev/urandom
произвольные большие запросы (source:extract_entropy_user
indrivers/char/random.c
), поэтомуdd
обычно безопасен при чтении с него. Однако чтение больших объемов данных требует времени. Если процесс получает сигнал,read
системный вызов возвращается до заполнения своего выходного буфера. Это нормальное поведение, и приложения должны вызыватьсяread
в цикле;dd
не делает этого по историческим причинам (dd
происхождение мрачное, но, похоже, оно начиналось как инструмент для доступа к лентам, которые имеют особые требования и никогда не были приспособлены для использования в качестве инструмента общего назначения). Когда вы проверяете прогресс, он посылаетdd
процессу сигнал, который прерывает чтение. У вас есть выбор между знанием, сколько байтовdd
полная копия воли (убедитесь, что она не прерывается - нет проверки хода выполнения, нет приостановки) или известно, сколько байтdd
до сих пор скопировал, и в этом случае вы не можете знать, сколько еще байтов будет скопировано.Версия
dd
в GNU coreutils (как в не встроенных Linux и в Cygwin) имеет флаг,fullblock
который указываетdd
на вызовread
в цикле (и то же дляwrite
) и, таким образом, всегда передает полные блоки. Сообщение об ошибке предполагает, что вы используете его; Вы должны всегда использовать его (как во входных, так и в выходных флагах), за исключением особых случаев (в основном, при доступе к лентам) - если вы используетеdd
вообще, то есть: обычно есть лучшие решения (см. ниже).Другой возможный способ быть уверенным в том,
dd
что нужно сделать, - передать размер блока, равный 1. Затем вы можете сказать, сколько байтов было скопировано из числа блоков, хотя я не уверен, что произойдет, еслиread
прервать a перед чтением первого байт (что не очень вероятно на практике, но может случиться). Однако, даже если это работает, это очень медленно.Общие рекомендации по использованию
dd
является не использоватьdd
. Хотяdd
часто объявляется как команда низкого уровня для доступа к устройствам, на самом деле это не так: все волшебство происходит в части файла (the/dev/…
) устройства,dd
это просто обычный инструмент с высоким потенциалом для неправильного использования, что приводит к потере данных , В большинстве случаев есть более простой и безопасный способ сделать то, что вы хотите, по крайней мере, в Linux.Например, чтобы прочитать определенное количество байтов в начале файла, просто вызовите
head
:Я сделал быстрый тест на моей машине и не заметил различий в производительности между
dd
большим размером блока иhead
.Если вам нужно пропустить несколько байтов в начале, отправьте
tail
вhead
:Если вы хотите увидеть прогресс, позвоните,
lsof
чтобы увидеть смещение файла. Это работает только для обычного файла (выходного файла в вашем примере), а не для символьного устройства.Вы можете позвонить,
pv
чтобы получить отчет о ходе работы (лучше, чем уdd
), за счет дополнительного элемента в конвейере (с точки зрения производительности, он едва заметен).источник
dd
команде, которые я не знал, что мне нужно было знать. Благодарю.dd
может использоваться безопасно благодаря егоfullblock
опции. Но если у вас есть GNU coreutils, вам не нужноdd
много. «Производные» такие как неdcfldd
являются , они не страдают от своих конструктивных дефектов, поэтому мой ответ к ним не относится. Огромное, подавляющее большинство людей, которые используют , не нашли достаточно времени, чтобы понять это (самое большее, они нашли время, чтобы подумать, что понимают это), и то, как они это используют, приводит к потере данных.dd
dd
Предупреждение возникает, когда
dd
не удается получить достаточно данных для заполнения блока за одно чтение. Это происходит с ошибочными или медленными источниками данных или источниками, которые записывают данные в меньших единицах, чем запрашиваемый размер блока.Нет проблем с целостностью данных, но проблема в том, что
dd
частичное чтение все еще считается блоком чтения.Если вы не используете эту
count
опцию, предупреждение вряд ли имеет значение, это просто соображение производительности. Но при этомcount
вы не получите объем запрошенных вами данных. Из-за частичного чтенияof
будет меньше, чемcount*bs
в конце.Поэтому, когда вы используете
count
, технически вы должны всегда использоватьiflag=fullblock
также.+x
Должно быть количество частичных блоков.источник
^ Это будет просто работать. Дезинформация, которая в противном случае была здесь, явно ложна.
dd
Буферы являются явными, и поэтому для буферизации ввода для подсчета вхождений необходимо явно буферизовать. Это все. Не покупай фуд.источник