Рейтинг: 5 / 5

Звезда активнаЗвезда активнаЗвезда активнаЗвезда активнаЗвезда активна
 

Обычные варианты применения команды dd

Начнем знакомство с операндами команды dd:

if=filename (input file) Этот операнд задает входной файл; если он не указан, то по умолчанию используется стандартный ввод. Этим файлом может быть также файл (нода) устройства, например /dev/hda1, или специфические файлы типа /dev/zero.

 

of=filename (output file) Задает выходной файл; если он не указан, то по умолчанию используется стандартный вывод (экран монитора).

Знакомство с этими двумя операндами уже дает нам возможность использовать программу dd для копирования файлов.

Простое копирование.

dd if=/home/ya/Desktop/shema.txt of=/home/ya/Desktop/shema.html

3+1 записей считано
3+1 записей написано
скопировано 1549 байт (1,5 kB), 0,427457 секунд, 3,6 kB/s

Как мы видим, программа dd сняла копию файла shema.txt и записала данные в файл shema.html. При этом она выдала нам сообщение.

Разберемся, о чем говорится в этом сообщении. Команда dd считывает и записывает блоками по N байт в каждом. Поскольку мы не задали в командной строке размер блока, то программа использовала размер блока по умолчанию, равный 512 байт. Всего скопировано 1549 байт, как записано в последней строке сообщения. "3+1 записей считано" означает число полных блоков - 3 плюс один неполный блок, содержащий оставшиеся байты 1549-(3*512)=13. То же относится и к строке "3+1 записей написано".

Теперь самое время разобраться с размером блока.

Сразу скажу, что блок команды dd не имеет никакого отношения к блокам данных файловой системы. Программа dd работает с необработанными "сырыми" (raw data) данными на низком уровне, т.е. на уровне секторов жесткого диска. А любая файловая система является надстройкой над этим уровнем. Правильнее было бы назвать блок буфером. Мы имеем два буфера - входной буфер и выходной буфер. Величина буфера задается операндом bs (block size) и исчисляется в байтах. Например, запись bs=512 означает, что нами установлен размер блока (буфера) в 512 байт. Кстати это значение и используется по умолчанию. Если величина блока не указана, dd использует блоки по 512 байт, что подходит для абсолютного большинства задач. Итак, величина буфера задана, dd создает 512-байтный буфер считывания, посылает единственный запрос на чтение со входного файла, затем создает 512-байтный буфер записи и посылает единственный запрос на запись в выходной файл. Давайте сравним работу программы dd и программы cp при копировании дискеты.

 

dd if=/dev/fd0 of=floppy.img bs=1474560

1+0 записей считано
1+0 записей написано
скопировано 1474560 байт (1,5 MB), 0,0438156 секунд, 33,7 MB/s

Может возникнуть вопрос: "А почему именно 1474560 байт, а не 1440 000, как принято считать размер дискеты?" Это значение складывается из: 2 головки, 80 цилиндров, 18 секторов/дорожку при длине сектора 512 байт. Итого: 2*80*18*512=1474560 байт.

Команде же

 

cp /dev/fd0 floppy.img

требуется послать 360 запросов по 4096 байт (размер блока данных), что даст те же 360*4096=147560 байт. Для файла размером 1.44Mб это может показаться незначительным, но когда производятся операции с большими объемами данных, уменьшение числа системных вызовов приводит к существенному повышению быстродействия системы.

Итак, размер блока задается операндом

bs=n(байт)

Существуют и другие способы задания этого параметра, например при помощи знака , который понимается как умножение. Только что мы вычисляли точный размер дискеты, тем же способом можно задать величину блока:

bs=2х80х18х512

или используя суффиксы:

bs=2x80x18b

где суффикс b означает 512, а вся запись аналогична предыдущей. Применяются следующие суффиксы:

 

w означает 2 (в некоторых реализациях 4)
b означает 512
k означает 1024

Короче говоря, как часто бывает в Юниксе, все максимально запутано и требует недюжинной памяти. Но и это еще не все. Кроме bs, существуют еще три операнда размера блока:

ibs=n(байт) Этот операнд определяет размер входного блока. Правила его задания такие же, как для bs.

obs=n(байт) Этот операнд определяет размер выходного блока. Правила его задания такие же, как для bs.

bs является как бы старшим операндом, и если он задан, то ibs и obs игнорируются. ibs и obs нужны в тех случаях, когда необходимо задать различные значения входного и выходного блоков.

И четвертый операнд, связанный с размером блока:

cbs=n(байт) Определяет размер буфера (блока) преобразования. О нем мы будем говорить в главе, посвященной преобразованиям форматов данных.

Теперь, когда мы умеем задавать размеры блока, мы можем выполнить очень важную задачу - снять резервную копию Главной загрузочной записи - MBR. Все, у кого на компьютере имеется несколько операционных систем, должны иметь такую копию, и обновлять ее при каждом изменении системы. MBR находится в 0 секторе первого раздела жесткого диска и занимает вместе с таблицей разделов ровно 512 байт.

Для того чтобы скопировать MBR, следует познакомиться с еще одним операндом:

count=n(блоков) Этот операнд определяет количество блоков, подлежащих копированию. Например запись

bs=512 count=100

означает приказ скопировать 100 блоков по 512 байт каждый. Здесь также возможно применение суффиксов, например

bs=512 count=1k

означает, что будет скопировано 1024 блока по 512 байт каждый.

Внимание! Операнд count имеет дело с блоками, а не с байтами!

Команда, которая скопирует нам MBR в файл backup.mbr выглядит так:

 

dd if=/dev/hda of=backup.mbr bs=512 count=1

1+0 записей считано
1+0 записей написано
скопировано 512 байт (512 B), 0,000358146 секунд, 1,4 MB/s

Резервная копия создана, теперь главное не забыть, где она лежит. И если какой-нибудь вредный дистрибутив криво установит нам загрузчик Grub, то мы спокойно проделаем обратную операцию:

 

dd if=backup.mbr of=/dev/hda bs=512 count=1

А если нам нужно не весь MBR, а только загрузочный код, который занимает первые 446 байт 0 сектора? Тогда придется изменить размер блока:

 

dd if=/dev/hda of=boot-code.mbr bs=446 count=1

 

1+0 записей считано
1+0 записей написано
скопировано 446 байт (446 B), 0,0345156 секунд, 1,4 MB/s

 

Если же мы хотим сохранить только таблицу разделов, а загрузочный код (скажем от Windows) нам больше не нужен? Для выполнения этой задачи нам нужно познакомиться еще с одним операндом:

skip=n(блоков) Этот операнд пропускает n блоков от начала входного (if) файла, а затем копирует указанное количество блоков.

Внимание! Операнд skip (как и count) имеет дело с блоками, а не с байтами! Поэтому размер блока следует выбирать вдумчиво. Что мы и сделаем:

 

dd if=/dev/hda of=part-table.mbr bs=1 count=66 skip=446

66+0 записей считано
66+0 записей написано
скопировано 66 байт (66 B), 0,034515 секунд, 11,9 kB/s

Может возникнуть вопрос: "Почему копировали 66 байт, хотя известно, что таблица разделов занимает 16*4=64 байта?" Дело в том, что последние два байта в таблице разделов занимает так называемая сигнатура (подпись) [55 аа], без которой ни один компьютер не опознает таблицу разделов. И поскольку мы делаем резервную копию, то, во избежание забывчивости и недоразумений при будущем восстановлении таблицы разделов, присоединили сигнатуру к таблице разделов.

Как вам нравится рисунок 5? Какой-то он непривычный (смещение на два байта) и неинформативный. Лучше бы иметь стандартную распечатку MBR, в котором первые 446 байт заменены, скажем, нулями. Если придется править вручную, будет намного удобнее. Команда dd позволяет и это. Только нужно применить еще один операнд:

seek=n(блоков) Этот операнд пропускает в выходном файле (of) n блоков, прежде чем начать туда запись.

Внимание! Операнд seek (как и skip и count) имеет дело с блоками, а не с байтами!

Место пропущенных блоков он заполняет нулями. Значит нам нужно применить такую команду:

 

dd if=/dev/hda of=part-table.mbr bs=1 count=66 skip=446 seek=446

66+0 записей считано
66+0 записей написано
скопировано 66 байт (66 B), 0,034515 секунд, 12,9 kB/s

Создание загрузочной дискеты из файла-образа.

Допустим, мы скачали из Интернета файл-образ чрезвычайно полезного загрузочного менеджера SBM (SmartBootManager) sbm.img. Теперь нужно создать загрузочную дискету SBM:

 

dd if=/путь/sbm.img of=/dev/fd0

Никаких дополнительных операндов не требуется, поскольку файл-образ точно рассчитывается под величину дискеты.

 

Пример 3. Разрезать 10 мегабайтный файл file.10m на два пяти-мегабайтных:

 

dd if=file.10m of=file1.5m bs=1M count=5 dd if=file.10m of=file2.5m bs=1M skip=5

 

Вывести на экран первые 100 байт содержимого файла schema.txt:

dd if=Desktop/shema.txt bs=100 count=1

1+0 записей считано 1+0 записей написано скопировано 100 байт (100 B), 0,00155746 секунд, 64,2 kB/s

Обратите внимание, что мы не указывали выходной файл (of). Поэтому команда dd по умолчанию воспользовалась стандартным выводом (экраном монитора).

 

Создание образа оптического диска:

dd if=/dev/cdrom of=image.iso bs=2k

При желании, с помощью полученного образа image.iso можно будет "прожечь" полноценный загрузочный диск (если, конечно, оригинал был загрузочным). Если копировать командой ср, то загрузочного диска не получишь.

 

Ускорениe работы некоторых Live CD.

На "слабых" машинах современные Live CD работают медленно, иногда очень медленно. Если на жестком диске выделить раздел, скажем hda7 размером в 900Мб (для CD) и скопировать в этот раздел весь CD целиком, то во многих случаях, при загрузки с CD загрузчик примет наш раздел жесткого диска за сам CD и начнет загрузку с него. В этом случае скорость работы сильно повышается, ведь работа с жесткого диска намного быстрее, чем с любого CD привода.

 

dd if=/dev/cdrom of=/dev/hda bs=2k

Этот фокус не всегда срабатывает, так как некоторые загрузчика не перебирают все файлы устройств по порядку. Например, Gentoo Live CD и Mandriva Spring Live CD, я только таким способом и смог запустить в графическом режиме на старом ноутбуке. А Mops Live CD на обман не поддается, и ищет чего-то другого.

 

Увеличить размер существующего файла до 1Гб без перезаписи:

dd if=/dev/zero of=file.name bs=1 count=0 seek=1G

 

Создание загрузочной дискеты Grub

Для создания загрузочной дискеты Grub, нужно записать файл stage1 в нулевой сектор дискеты, а файл stage2 в первый и последующие сектора. Файлы stage1 и stage2 обычно находятся в директории /boot/grub, если Grub у вас установлен, или в пакете, если Grub еще не установлен. Я не стану указывать путь к этим файлам, он у всех разный.

 

dd if=stage1 of=/dev/fd0 bs=512 count=1

Файл stage1 (загрузочный) занял свое место в загрузочном (0) секторе дискеты.

 

dd if=stage2 of=/dev/fd0 bs=512 seek=1 153+1 records in 153+1 records out

Команда dd пропустила один сектор (поскольку там уже записаны данные stage1, то нулями она его не заполнила) и записала весь файл stage2. Теперь с этой дискеты можно загружать Grub, и с его помощью запускать любую ОС на вашей машине.

 

Создание загрузочного образа

Сходную задачу выполняет Makefile ядра Линукс при создании загрузочного образа (boot image). В Alpha Makefile /usr/src/linux/arch/alpha/boot/Makefile программа srmboot на выходе выдает команду:

 

dd if=bootimage of=$(BOOTDEV) bs=512 seek=1 skip=1

Эта команда означает: пропустить (seek=1) первые 512 байт во входном файле (bootimage); начать запись со второго сектора устройства $(BOOTDEV). Типичное использование команды dd в том, чтобы пропустить исполняемую программу в заголовке, и начать запись в середине устройства, пропуская данные о томе и разделе. Нужно сказать, что малейшая ошибка в такого рода записях, может стоить вашему диску потери системных данных, поэтому будьте осторожны и проверьте все трижды.

Вывести на экран уже знакомый нам MBR.

Поскольку это двоичный файл, придется воспользоваться следующим конвейером:

dd if=/dev/hda bs=512 count=1 2>/dev/null | hexdump

Создание резервной копии жесткого диска прямо на другой диск:

dd if=/dev/hda of=/dev/sda conv=noerror,sync bs=4k

Выбор размера блока не случаен: при маленьких блоках процесс копирования затянется, Можно задать большие блоки, но тогда в случае ошибок, оставшиеся после ошибки части блока будут заполнены нулями. Поэтому чем больше блоки, тем больше информации вы потеряете.

Уж, коль скоро зашла речь о резервном копировании, вот еще пример, не относящийся к преобразованиям, но пусть они будут рядом.

 

Создание резервного образа жесткого диска:

dd if=/dev/hda | gzip > /mnt/hdb1/system_drive_backup.img.gz

Команда dd создает образ первого жесткого диска и по конвейеру (не забудьте про стандартный вывод по умолчанию) передает программе сжатия gzip. Сжатый образ затем помещается в файл system_drive_backup.img.gz, находящийся на другом диске (hdb1). Чтобы произвести обратное действие:

gzip -dc /mnt/hdb1/system_drive_backup.img.gz | dd of=/dev/hda

Программа gzip распаковывает (опция -d) файл, передает результат на стандартный выход (опция -c), по конвейеру данные поступают программе dd, которая записывает выходной файл (устройство /dev/hda).

Незаметно мы рассмотрели почти все значения (фильтры) операнда conv. Тут и ману конец. Но сначала несколько правил относящихся к взаимодействию операндов.

Правило 1. Все операнды обрабатываются до начала чтения входных данных. В практическом смысле это значит, что можно писать операнды в любом порядке - результат будет один. Скажем команда:

dd if=/dev/hda of=/dev/sda conv=noerror,sync bs=4k

равносильна команде

dd bs=4k conv=noerror,sync if=/dev/hda of=/dev/sda

Правило 2. Если операнды (кроме conv=) указаны более одного раза, будет использоваться значение из последней пары операнд=значение.

 

Еще примеры возможностей команды dd

Уничтожение всех данных в разделе hdc2, размером 1Гб:

Чтобы было невозможно восстановить содержимое этого раздела, заполним его нулями от первого до последнего байта.

dd if=/dev/zero of=/dev/hdc2 bs=1M

dd: запись `/dev/hdc2': No space left on device
957+0 записей считано
956+0 записей написано
скопировано 1003484160 байт (1,0 GB), 44,7713 секунд, 22,4 MB/s

А можно псевдослучайными байтами:

dd if=/dev/urandom of=/dev/hdc2 bs=1M

dd: запись `/dev/hdc2': No space left on device
957+0 записей считано
956+0 записей написано
скопировано 1003484160 байт (1,0 GB), 1050,83 секунд, 955 kB/s

Давайте проверим, что получилось. Возьмем на вскидку 1001 сектор раздела hdc2, который мы только что заполнили псевдослучайными байтами:

 

dd if=/dev/hdc2 bs=512 count=1 skip=1000


???:?+K▒^??8???/-O?L*lJ?N`????????_
?7$?.pXi(\kN]c??6@lJ2IM]Z?9iAVlm?6?wCm?;s???r?2\?&Sd>???!n??!????P???9!s-{? 0??-uK???H?a>?F[?S[
???▒w?JP(wt~W1????D? }E?cF>|?8{9 Q?t%7AnFtu
j?J??L?
xv?'??_bs??TP }Du?
1+0 записей считано
1+0 записей написано
скопировано 512 байт (512 B), 0,0114453 секунд, 44,7

Действительно, ахинея! Справедливости ради нужно заметить, что заполнение нулями при прочих равных условиях занимает на порядок меньше времени.

Кстати, таким же способом можно прочесть любой сектор, или группу секторов любого носителя.

 

Особые случаи применения команды dd

Команда dd применяется в судебной и криминалистической практике. Самое очевидное применение - снятие точных (побайтовых) копий с жестких дисков подозреваемого. Работать с ними удобнее (не нужно подключать диски физически), да и места займет немного.

 

dd if=/dev/hda of=/dev/case10img1

Другой случай. В руках криминалистов оказалась магнитная лента, подлежащая исследованию. Но неизвестен размер блока на этой пленке, а знание правильного размера многократно ускорит процесс прочтения. Можно попытаться определить размер блока при помощи команды dd:

 

dd if=/dev/st0 ibs=128 of=/dev/case10img1 obs=1 count=1

задав несуразный размер входного блока (ibs=128), мы провоцируем программу выдать сообщение об ошибке, в котором будет указан истинный размер блока.

Еще одно применение команды dd состоит в возможности порезать большой объем данных (жесткий диск) на кусочки, удобные для записи на другие носители (например DVD):

 

dd if=/dev/st0 bs=1M count=4000 of=/dev/case10img1

dd if=/dev/st0 bs=1M count=4000 skip=4000 of=/dev/case10img2

dd if=/dev/st0 bs=1M count=4000 skip=8000 of=/dev/case10img3

dd if=/dev/st0 bs=1M count=4000 skip=12000 of=/dev/case10img4

 

Источник http://rus-linux.net