У меня есть tar-архив одного образа диска. Размер изображения в этом tar-файле составляет около 4 ГБ. Я передаю вывод tar xf
в, dd
чтобы записать образ диска на SD-карту. Диск-дамп никогда не останавливается, пока карта не заполнится. Вот мой сеанс оболочки:
$ ls -l disk.img.tgz
-rw-r--r-- 1 confus confus 192M Okt 5 00:53
$ tar -tvf disk.img.tgz
-rw-r--r-- root/root 4294968320 2018-10-05 00:52 disk.img
$ lsblk -lb /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc 8:32 1 16022241280 0 disk
$ tar zxf disk.img.tgz -O | sudo dd status=progress conv=sync bs=1M of=/dev/sdc
[sudo] password for user:
15992881152 bytes (16 GB, 15 GiB) copied, 212 s, 75,4 MB/s
dd: error writing '/dev/sdc': No space left on device
0+15281 records in
15280+0 records out
16022241280 bytes (16 GB, 15 GiB) copied, 217,67 s, 73,6 MB/s
Почему? Он должен остановиться после того, как хит записал изображение объемом 4 ГБ в корзину на 16 ГБ и никогда не закончится!
pipe
tar
dd
disk-image
кон-е использование
источник
источник
dd
и записать его в другой файл?tar zxf disk.img.tgz -O | dd status=progress conv=sync bs=1M of=/path/to/some/file/on/disk
? Если так, это дает вам точную копию оригинального файла?conv=sync
? Возможно, вы хотели использоватьconv=fsync
?Ответы:
Это потому что ты делаешь это неправильно.
Вы используете,
bs=1M
но чтение из stdin, pipe, будет иметь меньшее чтение. На самом деле, по словам дд, вы не получили ни одного полного чтения.И тогда у вас есть,
conv=sync
что дополняет неполное чтение с нулями.dd
получил 0 полных и 15281 неполных чтений и записал 15280 полных блоков (conv = синхронизация заполнена нулями). Таким образом, вывод будет намного больше, чем ввод, пока не останется свободного места.Чтобы решить эту проблему, вы можете удалить
conv=sync
и добавитьiflag=fullblock
.Чтобы проиллюстрировать это, рассмотрим
yes
, который по умолчанию выбрасывает бесконечный "y \ ny \ ny \ n".С
dd bs=1M conv=sync
этим выглядит так:Таким образом, он получает неполный блок "y \ ny \ ny \ n" (0x00000 - 0x1e000, 122880 байт), а затем записывает оставшиеся 1M как нули (0x01e000 - 0x100000, 925696 байт). В большинстве случаев вы не хотите, чтобы это произошло. В любом случае результат является случайным, поскольку у вас нет реального контроля над тем, насколько неполным будет каждое чтение. Как и здесь, второе чтение больше не 122880 байт, а 73728 байт.
dd conv=sync
редко бывает полезным, и даже в тех случаях, когда это будет приветствоваться, например, при записи нулей, когда вы получаете ошибки чтения, с этим все пойдет не так.источник
dd
команды вstrace
(при условии Linux) показало бы, что за каждым коротким чтением из канала следовала полная запись в 1 МБ.dd
команда в корне сломана и непригодна для использования. Он определен для работы с отдельнымиread
s иwrite
s, но эти операции определены так, что они всегда могут производить короткие чтения или записи, и это не ошибка. Как следствие, поведениеdd
зависит от неопределенного поведения.dd
, но это привело меня к чему-то научиться у вас. В чем я до сих пор не совсем уверен, так это в том случае, если и когдаdd
это закончится. Я предполагаю, что это произойдет, но так как он фактически записывал 1 часть фактических данных и 9 частей нулей, он остановился бы после записи около 40G. Это верно?