Состояние перевода: На этой странице представлен перевод статьи dd. Дата последней синхронизации: 2 февраля 2022. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.
dd — это основная утилита, основной задачей которой является конвертация и копирование файлов.
Как и cp, по умолчанию dd делает точную копию файла, но позволяет контролировать параметры ввода-вывода на низком уровне.
Подробности можно почитать в dd(1) или полной документации.
Совет: По умолчанию dd ничего не пишет в консоль в процессе работы. Чтобы следить за процессом, можно использовать опцию status=progress.
Важно: Будьте крайне осторожны при использовании dd, так как её использование может необратимо уничтожить данные.
Установка
dd входит в состав GNU coreutils. Другие утилиты из этого пакета описаны в статье Основные утилиты.
Клонирование диска и восстановление
Команда dd — это простой, но универсальный и мощный инструмент. Она может использоваться для копирования, блок за блоком, независимо от типа файловой системы или операционной системы. Нередко dd используется в LiveCD.
Важно: Как и с любыми командами подобного рода, при использовании dd нужно быть очень осторожным; она может уничтожить данные. Запомните опции, задающие входной файл (if=) и выходной файл (of=), и не меняйте их местами! Всегда проверяйте, что целевой диск или раздел (of=) имеет равный или больший размер, чем исходный (if=).
Клонирование раздела
Копирование раздела 1 на диске /dev/sda в раздел 1 на диске /dev/sdb:
# dd if=/dev/sda1 of=/dev/sdb1 bs=64K conv=noerror,sync status=progress
Примечание: Проверяйте существование файла целевого устройства (в данном примере sdb1). Если он не существует, то dd создаст новый файл, который будет занимать место в вашей файловой системе.
Клонирование всего диска
Копирование физического диска /dev/sda в диск /dev/sdb:
# dd if=/dev/sda of=/dev/sdb bs=64K conv=noerror,sync status=progress
Эта команда скопирует диск целиком, в том числе таблицу разделов, загрузчик, разделы, UUID и данные.
bs=устанавливает размер блока. По умолчанию 512 байт, что является «классическим» размером блока для жёстких дисков с начала 1980-х годов, но не самым удобным. Используйте большее значение, 64K или 128K. Также прочитайте предупреждение ниже, потому что это не просто «размер блока» — это также влияет на обработку ошибок чтения. Смотрите [1] и [2] для получения подробной информации и определения наилучшего значения bs для вашего случая.noerrorуказывает dd продолжить работу, игнорируя все ошибки чтения. По умолчанию dd прекращает работу при любой ошибке.syncзаполняет входные блоки нулями, если были ошибки чтения, чтобы смещения данных оставались правильными.status=progressпоказывает статистику передачи данных, которая позволяет оценить время завершения.
Примечание: Размер блока, который вы указываете, влияет на то, как обрабатываются ошибки чтения (смотрите ниже). Для восстановления данных используйте ddrescue.
Утилита dd технически имеет «размер входного блока» (IBS) и «размер выходного блока» (OBS). Когда вы устанавливаете bs, вы фактически устанавливаете и IBS, и OBS. Обычно, если размер блока, скажем, 1 МиБ, dd считывает 1024×1024 байт и записывает столько же байт. Но если произойдет ошибка чтения, всё пойдет не так. Многие думают, что dd «заполнит ошибки чтения нулями», если вы используете опции noerror,sync, но это не так. dd, согласно документации, дополнит размер OBS до размера IBS после завершения чтения, что означает добавление нулей в конце блока. То есть, весь 1 МиБ будет испорчен из-за одной ошибки чтения в 512 байт в начале чтения: 12ERROR89 станет 128900000 вместо 120000089.
Если вы уверены, что ваш диск не содержит ошибок, вы можете использовать больший размер блока, что увеличит скорость копирования в несколько раз. Например, изменение bs с 512 до 64K изменило скорость копирования с 35 МБ/с до 120 МБ/с на простой системе Celeron 2,7 ГГц. Но имейте в виду, что ошибки чтения на исходном диске будут в конечном итоге выглядеть как ошибки блоков на целевом диске, то есть одна ошибка чтения 512 байт испортит весь выходной блок размером 64 КиБ.
Примечание:
- Чтобы сделать UUID файловых систем ext2/3/4 снова уникальными после копирования, используйте
tune2fs /dev/sdXY -U randomдля каждого раздела. Для разделов подкачки используйтеmkswap /dev/sdXY. - Если вы копируете GPT-диск, вы можете использовать sgdisk для рандомизации GUID диска и разделов и восстановления их уникальности.
- Изменения таблицы разделов, которые внёс dd на целевом диске, не регистрируются ядром. Чтобы попросить ядро перечитать таблицы разделов без перезагрузки, можно использовать утилиту partprobe (часть GNU Parted).
Резервное копирование таблицы разделов
Смотрите fdisk (Русский)#Резервное копирование и восстановление таблицы разделов или GPT fdisk (Русский)#Резервное копирование и восстановление таблицы разделов.
Создание образа диска
Загрузитесь в LiveCD и убедитесь, что разделы исходного диска не примонтированы.
Затем смонтируйте целевой диск и запишите на него резервную копию:
# dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c > /путь/к/копии.img.gz
При необходимости (например, если результирующие файлы будут храниться в файловой системе FAT32) можно разделить образ диска на несколько частей (смотрите также split(1)):
# dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c | split -a3 -b2G - /путь/к/копии.img.gz
Если не хватает свободного места на локальном диске, можно отправить образ через ssh:
# dd if=/dev/sda conv=sync,noerror bs=64K | gzip -c | ssh user@local dd of=копия.img.gz
Наконец, сохраните дополнительную информацию о геометрии диска, необходимую для интерпретации таблицы разделов, хранящейся в образе. Наиболее важной из них является размер цилиндра.
# fdisk -l /dev/sda > /путь/к/list_fdisk.info
Примечание: Вы можете использовать размер блока (bs=), равный объёму кэша на диске, с которого выполняется копирование. Например, bs=8192K подходит для кэша 8 МиБ. Упомянутые в этой статье 64 КиБ лучше, чем стандартные bs=512 байт, но при большем bs= копирование будет ещё быстрее.
Совет: gzip использует всего одно ядро процессора для сжатия, из-за чего скорость копирования может оказаться сильно меньше, чем скорость записи на современных накопителях. Чтобы использовать многоядерное сжатие и быстрее создать образ диска, можно, например, установить пакет pigz и просто заменить команду gzip -c на pigz -c. Для больших дисков это может сэкономить часы. Также можно попробовать другие алгоритмы сжатия, например zstd.
Восстановление системы
Чтобы восстановиться из такой резервной копии:
# gunzip -c /путь/к/копии.img.gz | dd of=/dev/sda
Если образ был разделён на несколько частей командой split, используйте другую команду (обратите внимание на звёздочку):
# cat /путь/к/копии.img.gz* | gunzip -c | dd of=/dev/sda
Патчинг бинарных файлов
Если нужно заменить заменить три байта FF C0 14 по смещению 0x123AB, это можно сделать с помощью такой команды:
# printf 'xffxc0x14' | dd seek=$((0x123AB)) conv=notrunc bs=1 of=/путь/к/файлу
Резервное копирование и восстановление MBR
Перед внесением изменений на диск можно создать резервную копию таблицы разделов и схемы разделов диска. Также можно использовать резервную копию для копирования одной и той же схемы разделов на несколько дисков.
MBR хранится в первых 512 байтах диска. Она состоит из 4 частей:
- Первые 440 байт содержат загрузочный код (загрузчик).
- Следующие 6 байт содержат сигнатуру диска.
- Следующие 64 байта содержат таблицу разделов (4 записи по 16 байт каждая, по одной записи на каждый основной раздел).
- Последние 2 байта содержат сигнатуру загрузки.
Сохранение MBR в mbr_file.img:
# dd if=/dev/sdX of=/путь/к/mbr_file.img bs=512 count=1
Также можно извлечь MBR из полного образа диска dd:
# dd if=/путь/к/образу.img of=/путь/к/mbr_file.img bs=512 count=1
Для восстановления (будьте осторожны, это уничтожит существующую таблицу разделов, а вместе с ней и доступ ко всем данным на диске):
# dd if=/путь/к/mbr_file.img of=/dev/sdX bs=512 count=1
Важно: Восстановление MBR с несоответствующей таблицей разделов сделает ваши данные нечитаемыми и практически невозможными для восстановления. Если вам просто нужно переустановить загрузчик, смотрите соответствующие страницы, поскольку они также используют DOS compatibility region: GRUB (Русский) или Syslinux (Русский).
Если вы хотите восстановить только загрузчик, но не информацию о разделах, просто восстановите первые 440 байт MBR:
# dd if=/путь/к/mbr_file.img of=/dev/sdX bs=440 count=1
Восстановление только таблицы разделов без затрагивания загрузчика и сигнатуры:
# dd if=/путь/к/mbr_file.img of=/dev/sdX bs=1 skip=446 count=64
Удаление загрузчика
Чтобы стереть загрузочный код MBR (может быть полезно, если вам нужно сделать полную переустановку другой операционной системы), можно обнулить первые 440 байт:
# dd if=/dev/zero of=/dev/sdX bs=440 count=1
Решение проблем
Partial read
Файлы, созданные с помощью dd, могут иметь меньший размер, чем запрошено, если полный входной блок недоступен и системный вызов read(2) завершается раньше времени. Это может произойти при чтении из pipe(7) или при чтении с /dev/random и недостаточной энтропии[3], или с /dev/urandom при чтении более 32 МиБ[4].
Возможно, но не гарантировано, что dd предупредит вас об этой проблеме:
dd: warning: partial read (X bytes); suggest iflag=fullblock
Решается это так, как и предлагает предупреждение: добавлением iflag=fullblock к команде dd:
$ dd if=/dev/random of=bigsecret.img bs=1K count=1 iflag=fullblock $ dd if=/dev/urandom of=bigsecret.img bs=40M count=1 iflag=fullblock
Примечание: Крайне желательно всегда использовать iflag=fullblock при чтении из /dev/random или /dev/urandom.
Для /dev/urandom также можно задать большее число копируемых блоков:
$ dd if=/dev/urandom of=bigsecret.img bs=1M count=40
При чтении из pipe альтернативой для для iflag=fullblock может быть прописывние для bs значения PIPE_BUF, которое определено в /usr/include/linux/limits.h [5]. Например:
$ cat input.img | dd of=output.img bs=4k count=100
I see four workable answers here:
-
The
hdparmmethod posted by garethTheRed is probably best if you are connected directly to your computer. Apparently, though, if you try it connected via USB, you can brick your drive. If you are doing this for a drive you are about to dispose of, then that may be a good thing. However, you probably want to secure erase before discarding. -
The technique reported by imz — Ivan Zakharyaschev will work, but may be very slow. I would suggest if you do not want the data to be recoverable, use
/dev/urandominstead of/dev/zero; e.g.,dd iflag=fullblock oflag=direct conv=noerror,notrunc if=/dev/urandom of=/dev/sdX -
I would advice against the following. For something faster that does the same thing, use the technique reported by maxschlepzig (in the question):
ddrescue --verbose --force --nosplit /dev/urandom /dev/sdXThis will be faster than the
ddcommand, but not as fast as thehdparmcommand. See below why I don’t recommend this… -
The
badblockscommand will also work, but you can’t randomize the data that way, and again it will be very slow.
Finally, I would be remiss if I did not point out the number one reason people want to completely erase a disk is they are about to dispose of it. In that case, if you haven’t already, you might want to try and recover the disk first. If you read a block and it returns the I/O error, then next time you write to the same block the disk will try to reallocate a different block from a reserve list. Once the reserve list is full then you will get I/O errors on writes. That is when you really should discard the drive.
So you can do something simple like:
dd if=/dev/sdX of=/dev/null conv=noerror
And, then, to rewrite the bad blocks, just something like:
dd if=/dev/zero of=/dev/sdX bs=128k
If this command works, if you are brave, you can reformat your disk and use it again.
Alternatively, you can run the badblocks command on the disk twice. The second time it should report no bad blocks…
badblocks -v -s -w -t random /dev/sdX
badblocks -v -s -w -t random /dev/sdX
This will take longer, but is more reliable.
It is also worth noting that none of the techniques really do a secure erase, except the hdparm command. Remember all those bad blocks? Those still have some of your original data mostly intact. A data recovery expert could access these to see a small amount of what was previously on your hard drive.
In regards to ddrescue and why I advice against it, I have the following antidote:
The problem is ddrescure will be TOO good at ignoring errors. I had a hard drive that consistently with dd dropped write speed at about the 102 GB mark and started producing a write errors at the 238 GB mark. I was quite impressed that ddrescue continued to churn through the disk at a constant speed, even reporting no errors. 17 hours later, when it was at the 1300 GB in when I happened to notice the drive light itself stopped flashing. A quick check revealed the whole USB enclosure had gone offline. I pulled the drive out of the cradle. I noticed ddrescue just happily reported it was still copying with no errors, even with the disk in my hands. I plugged the disk into another machine and found it was now a brick.
I don’t blame ddrescue for making the drive a brick. The drive was failing and would become a brick. I just find disturbing ddrescue doesn’t even give an error count of how many write errors it is ignoring. In this usage, ddrescue leaves you think it has been completely successful, regardless of all write failures. The fact is it should not have been able to continue at full speed in the section with the slow down. The reason that section was slow, is many blocks had been relocated by the drive, causing lots of seeking when accessing that section. So that is probably the point when ddrescue’s output became fictional.
������������� ������� ��������� ��������� ���������� (man-��)
dd (8)
������� ������������� |
dd(1M) |
��������
dd — �������������� � ����������� �����
���������
- /usr/bin/dd [ �������=�������� … ]
��������
������� dd �������� ��������� ������� ���� � ��������� ��������, ��������
��� ������������� ��������������. �� ��������� ������������ ����������� �������
� ����������� �������� ������. ����� �������� ������� ������ �� ������� �
�������� �����, ����� ������ ����������� ����������� �����-������. ������ ������
�������� � ������; �������� ������� ����� ������������� ���������� k, b
��� w, ��������� ��������� �� 1024, 512 � 2, ��������������.
����� ����� ����� ��������� ��������� x, ����������������� ��� ���������.
������� dd ����� ������ ������� ���� �� ������ ����� ��������� �������;
����� ��� ������������ ������, �������� ���������� ����� ������, ������� �����
���� ������ ���������� �������. ������� dd ��������� ����� ��������
�������������� � ���������� ������������ ������ � �������� ���� ������� ���������
��� ������ �������.
������� cbs ������������ ������ ���� ������ ��������������
ascii, asciib, unblock, ebcdic, ebcdicb,
ibm, ibmb ��� block. � ������ ���� ������� ������� cbs
���������� � ����� ��������������, ����������� ����� ���������
�������������� ��������, ��������� ������� ��������� � ����� ��������
������ � �������� ���� ����������� ������ ����� ������.
� ��������� ���� ������� ������� ������ �� ������� ����� ������
����������� � ����� �������������� � ����������� ��������� ��� ��������� ������
���������� �������. ��������������, ��� ����� ASCII
�������� ������� ����� ������. ���� �������� cbs �� ������ ��� ����� 0,
����� ascii, asciib, ebcdic, ebcdicb, ibm
� ibmb ����������� ����� �������� �� ������� ��������� ������ �������� �����;
����� unblock � block �������� � �������� ����������� �����.
����� ���������� ������ dd ���������� ���������� ������ ��� ���������
����������� � �������� ������.
��������
�������������� ��������� ��������:
����������� ��� ������� ������� ��������, � ������������ ��
��������� LC_CTYPE
| if=���� | ������ ������� ����; �� ��������� ������������ ����������� ������� �����. | ||||||||||||
| of=���� |
������ �������� ����; �� ��������� ������������ ����������� �������� �����. ���� ������������ �� ������ �������������� seek=expr, �������� ���� ����� ��������� ����� ������� �����������, ���� ������ �� ������ ������� conv=notrunc. ���� ������ ������� seek=expr, �� �� ������ conv=notrunc, � ���������� � �������� ����� ��������� ������ �����, ����������� �������� dd. (���� ������ ������������ ����� ���� ������ �������� ����� ������, ��� ������� ������ ��������� �����, � ���������� ����������� �������� ���� ������ ������.) |
||||||||||||
| ibs=n | ������ ������ �������� ����� — n ������ (�� ��������� — 512). | ||||||||||||
| obs=n | ������ ������ ��������� ����� — n ������ (�� ��������� — 512). | ||||||||||||
| bs=n |
������������� ������� �������� � ��������� ����� ������� n ������, ������������� ��������� ibs= � obs=. ���� �� ������� ������� ���������, ����� sync, noerror � notrunc, ������ ������� ���� ����� ��������������� ������������ �� �����, � �� ���������� �� ������� ������. |
||||||||||||
| cbs=n |
������ ������ ����� �������������� (n ������, �� ��������� — 0) ��� ��������� block � unblock. ���� ������� cbs= �� ������ ��� ������ �������� 0, ������������� ��������� block � unblock ���� �������������� ����������.
��� ����� ������������ ������ ���� ������� �������������� |
||||||||||||
| files=n |
�������� � ������������� n ������� ������, ������ ��� ��������� ������ (����� ����� ������ ���� ������� ������ ������� � ����� ��� ������� ������������ ����������). |
||||||||||||
| skip=n |
���������� n ������� ������ (��������� ��������� ������ �����) ����� ������� �����������. ���� �� ����� ����� ������������, ���������� dd ��������� ��� ������ �������� �����; ���� �� ������������ �� ����� ������, ����� ����� ��������� � ���������������. |
||||||||||||
| iseek=n |
������������ �� n ������ � ������ �������� ����� ����� ������������ (������� ��� ������ �� �����, ��� skip ����� �������� ������ ��������). |
||||||||||||
| oseek=n | ������������ �� n ������ �� ������ ��������� ����� ����� ������������. | ||||||||||||
| seek=n |
���������� n ������ (��������� �������� ������ ��������� �����) � ������ ��������� ����� ����� ������������. ���� �� ����� ������ ������������, ������������ ����� ����� ���������, � ������������ �� �������� ����� ����� �� ���������� �������� (���� �������� ������) ����� ���������� �������� �������; ���� �� �� ����� ����� ������������, ���������� dd ��������� ������ ������ �� ���������� �������� ��� ��������� ����� ���, ��� ������� ����. |
||||||||||||
| count=n | �������� ������ n ������� ������. | ||||||||||||
| conv=��������[,��������…] |
����� �������� ������� �� ���������� ������:
�������� ascii (��� asciib), ebcdic |
||||||||||||
| block |
������������� ������� ���� ��� ������������������ ������� ���������� �����, ����������� ��������� ����� ������ ��� �������� ����� ����� (EOF), ���������� �� ������� �������� �����. ������ ������ ������������� � ������ ������������� �����, ���������� �������� ����� ��������������. ��� ������� ����� ������ �� ������� ������ ���������; � ������� ��� ������������� ����������� �������, ����� ��������� ����. ������, ����� ������� ��������� ������ ����� ��������������, ��������� �� ����� �������; ������� �������� � ���������� ��������� �����. |
||||||||||||
| unblock |
����������� ������ ������������� ����� � ������ ���������� �����. ������ ���������� ������, ������ ������� ����� �������������� (��� ���������� ����� �������� �����, ���� �� ������, ��� ������ � ����� ��������������), ������� ��� ��������� ������� � ��������� ������ ����� ������. |
||||||||||||
| �������� block � unblock — �����������������. | |||||||||||||
| lcase |
����������� ��� ������� �������� ��������, � ������������ �� ��������� LC_CTYPE, � ������ �������. �������, ��� ������� �������������� � ������ �� ������, �� ����������. |
||||||||||||
| ucase | |||||||||||||
| �������� lcase � ucase — �����������������. | |||||||||||||
| swab |
������������ ����� � ������ ������� ����. ���� � ������� ������� ������ �������� ���������� ������, ��������� ���� ������������. |
||||||||||||
| noerror |
�� ������������� ��������� � ������ ������ ������. ��� ������������� ������ ������ � ����������� ����� ������ �������� ��������������� ���������, � ����� — ������� ������� � �������� ���� � ��� �� �������, ��� � ��� ���������� ������. ���� ������ �������������� sync, ����������� ������� ������ ����� �������� �������� �������; � ��������� ������, ������� ������� ���� ������ �� �������� � �������� ����. |
||||||||||||
| notrunc |
�� ������� �������� ����. ��������� ����� ��������� �����, �� ���������������� ���� ��� ���� ������ dd. (��. ����� �������������� ������� of=����.) |
||||||||||||
| sync |
��������� ������ ������� ���� �� ������� ������, ����������� ��������� ibs=, �������� ������� �����. (���� ������ ����� ������� block ��� unblock, ����������� �������, � �� ������� �����.) |
, � ������� �������. �������, ��� �������
�������������� � ������ �� ������, �� ����������.
���� �������� (����� conv=) ������� ����� ������ ����,
����� �������������� �������� �� ��������� ���� �������=��������.
��� ��������� bs=, cbs=,
ibs= � obs= ���������� ������� ���������,
�������� ������ � ������. ��� ��������� ����� ����:
- ������������� ����� ���������� ������
- ������������� ����� ���������� ������ � ��������� k,
�������� ��������� �� 1024 - ������������� ����� ���������� ������ � ��������� b,
�������� ��������� �� 512 - ����� ��� ����� �������������� ����������� �������
(� ��� ��� ��������� k ��� b), ������������ �������� x, ��������
������������ ��������������� ��������.
��� �������� �������������� �� ������ ������ ������� ������.
�������������
�������� ������ ������� dd � �������, ����� ������� �����������
2 ������ (2**31 ������) ��. �� �������� ����������� �����������
largefile(5).
�������
������ 1: ����������� � ������ �������� �� ������:
� ��������� ������� ����������� ����������� �� �������� 0 �� �������
1 � �������������� ����������� ���� ��������������� ���������.
example% dd if=/dev/rmt/0h of=/dev/rmt/1h
������ 2: ��������� ������ 10 ������ ������������ �������� ������
� ��������� ������� ��������� ������ 10 ������ ������������ �������� ������.
example% dd ibs=10 skip=1
������ 3: ������ ����� � ��������� (ASCII) ����
� ��������� ������� �������� ����� � ������� � ��������� EBCDIC,
��������������� �� ������ 80-�������� �������, � ASCII-���� x:
example% dd if=/dev/tape of=x ibs=800 cbs=80 conv=ascii,lcase
������ 4: ������������� conv=sync ��� ������ �� �����
� ��������� ������� ������������ ������������� (conv=sync)
��� ������ �� �����:
example% tar cvf — . | compress | dd obs=1024k of=/dev/rmt/0 conv=sync
���������� �����
�������� ���������� �����
LC_CTYPE, LC_MESSAGES
� NLSPATH, �������� �� ������ dd,
��. �� �������� ����������� �����������
environ(5).
������ ������
��������� ����������� �� ���������� ���������� ������� ������:
| 0 | ������� ���� ������� ����������. |
| >0 | ��������� ������. |
���� ��� ������ ��������� ������ � �� ������� ��������������
noerror, �������� �������������� �������� ���� ����� ������� � ��������
����, ����� ������ ��������������� ��������� � ����������� ����� ����������.
��� ������������� ����� ������ ������ ����� ������ ��������������� ���������
� ����������� ����� ����������.
��������
�������� ��������� ��������� ��. �� �������� ����������� �����������
attributes(5):
| ��� �������� | �������� �������� |
| �������� � ������ | SUNWcsu |
������
-
cp(1),
sed(1),
tr(1),
attributes(5),
environ(5),
largefile(5)
�����������
f+p records in(out)
- ���������� �������� � �������� ����������� (����������) ������
����������
�� ����������� dd ��� ����������� ������ �� ����� �������� ������� � ������,
���� � ���� �������� �������� ������ ������� ������.
��� ������������� �������� ���������� ��� ����������� ������ ��������� ����
����� �������� �������� ������� �� ������� �����.
����� ������� dd ������ �� ������������ ������ � ������ ��������
ibs=X � obs=Y, ��������� ����� ������ ����������� � ����� �������
Y. ���� ������������ ������� bs=Z, �������� ����� ������ ����� ����� ������,
��� ����������� �� �������� ������.
��� ������������� dd ��� ����������� ������ �� �����,
������ ����� ������ ���� ������� ������� ������� �� ���������� (��������,
512 ������). ��� ����������� �� ����� ������ ������������� �������
����������� ������� tar(1)
��� cpio(1).
��� ��������� ������� SIGINT ������� dd ����� ����������� ������ ������
���������� � ��������� � ����������� ����� ������. ��� ��������� ��������
������������ ����������� �����������.
Copyright 2002 �. �������,
OpenXS Initiative, ������� �� ������� ����

В Linux все является файлом, и блочные устройства не исключение. Часто нам приходится работать с блочными устройствами. Как пользователи Linux, мы выполняем различные операции с блочными устройствами, например, – создание резервной копии диска или раздела, резервное копирование главной загрузочной записи (MBR), создание загрузочного USB-накопителя и т.д. Конечно, мы можем использовать графические инструменты для выполнения всех этих операций. Однако большинство администраторов Linux предпочитают использовать команду dd из-за ее богатой функциональности и надежности.
Синтаксис команды dd
Наиболее распространенный синтаксис команды dd следующий:
dd [if=][of=]
В приведенном выше синтаксисе:
- if – представляет входной или исходный файл.
- of – представляет выходной или конечный файл.
Предупреждение – Важно отметить, что команда dd должна использоваться очень осторожно при работе с блочными устройствами. Небольшая ошибка может привести к необратимой потере данных. Поэтому настоятельно рекомендуется сначала опробовать эти операции на тестовой машине.
1. Как скопировать файл в Linux
Одним из основных способов использования команды dd является копирование файла в текущий каталог. Для начала создадим простой текстовый файл:
echo "this is a sample text file" > file-1.txt
Теперь создадим его копию с помощью команды dd:
dd if=file-1.txt of=file-2.txt
В этом примере параметр if представляет исходный файл, а параметр of – конечный файл.

Разве она не похожа на команду cp? Тогда что особенного в команде dd?
Команда dd намного мощнее обычной команды cp.
2. Как преобразовать текст из нижнего регистра в верхний
Команда dd позволяет нам выполнять преобразование регистра. Для этого мы можем использовать с ней параметр conv.
Чтобы понять это, сначала выведите содержимое файла file-1.txt:
cat file-1.txt this is a sample text file
Теперь преобразуем содержимое файла в верхний регистр с помощью следующей команды:
dd if=file-1.txt of=upper-case.txt conv=ucase
В этом примере опция conv=ucase используется для преобразования строчных букв в прописные.
Наконец, проверьте содержимое вновь созданного файла:
cat upper-case.txt THIS IS A SAMPLE TEXT FILE

3. Как перевести текст из верхнего регистра в нижний
Аналогичным образом мы можем использовать команду dd для преобразования букв верхнего регистра в буквы нижнего регистра:
Давайте воспользуемся опцией conv=lcase для преобразования букв верхнего регистра в строчные:
dd if=upper-case.txt of=lower-case.txt conv=lcase
Теперь отобразим содержимое созданного файла и убедимся, что преобразование было выполнено правильно:
cat lower-case.txt this is a sample text file

4. Избегайте перезаписи файла назначения в Linux
По умолчанию команда dd заменяет файл назначения, что означает, что она перезапишет файл, если он существует в месте назначения с тем же именем.
Однако, мы можем отключить это поведение по умолчанию, используя опцию conv=excl, как показано на рисунке.
dd if=file-1.txt of=file-2.txt conv=excl dd: failed to open 'file-2.txt' File exists
Здесь мы видим, что команда dd прервала операцию, потому что файл с тем же именем присутствует в месте назначения.
5. Добавление данных в файл с помощью команды dd
Иногда мы хотим обновить файл в режиме добавления, что означает, что новое содержимое должно быть добавлено в конец конечного файла.
Мы можем достичь этого, комбинируя два флага – oflag=append и conv=notrunc. Здесь oflag представляет собой флаг вывода, а опция notrunc используется для отключения усечения в месте назначения.
Чтобы понять это, сначала создадим новый текстовый файл:
echo "append example demo" > dest.txt
Далее, добавим содержимое в файл dest.txt с помощью следующей команды:
dd if=file-1.txt of=dest.txt oflag=append conv=notrunc
Теперь, проверим содержимое файла dest.txt:
cat dest.txt append example demo this is a sample text file

6. Пропуск байтов или символов при чтении входного файла
Мы можем указать команде dd пропустить первые несколько символов при чтении входного файла, используя опции ibs и skip.
Сначала выведем содержимое файла file-1.txt:
cat file-1.txt this is a sample text file
Следующая команда:
dd if=file-1.txt of=file-2.txt ibs=8 skip=1
Теперь проверим содержимое файла file-2.txt:
cat file-2.txt a sample text file

В приведенном выше выводе видно, что команда пропустила первые 8 символов.
7. Резервное копирование раздела диска Linux с помощью команды dd
До сих пор мы обсуждали основные примеры команды dd, не требующие root-доступа. Теперь давайте рассмотрим некоторые продвинутые случаи использования.
Как и в случае с файлами, мы можем сделать резервную копию раздела диска с помощью команды dd. Например, приведенная ниже команда создает резервную копию раздела /dev/sda1 в файл partition-bak.img:
sudo dd if=/dev/sda1 of=partition-bak.img

8. Восстановление раздела диска Linux с помощью команды dd
В предыдущем примере мы создали резервную копию раздела /dev/sda1 в файл partition-bak.img.
Теперь давайте восстановим его в раздел /dev/sdb1 с помощью следующей команды:
sudo dd if=partition-bak.img of=/dev/sdb1

Важно отметить, что размер целевого раздела должен быть равен или больше размера резервной копии.
9. Резервное копирование всего жесткого диска Linux с помощью команды dd
Диск может иметь несколько разделов. Поэтому создание и восстановление резервной копии каждого раздела может занять много времени при увеличении количества разделов. Чтобы преодолеть это ограничение, мы можем создать резервную копию всего диска, как и разделов.
Так, давайте создадим резервную копию диска /dev/sda с помощью следующей команды:
sudo dd if=/dev/sda of=disk-bak.img

Приведенная выше команда создает резервную копию всего диска, включая его разделы.
10. Восстановление жесткого диска Linux с помощью команды dd
Как и разделы, мы можем восстановить резервную копию всего диска. В предыдущем примере мы сделали резервную копию всего диска в файл disk-bak.img. Теперь воспользуемся тем же для восстановления резервной копии на диске /dev/sdb.
Сначала удалим все разделы с диска /dev/sdb и проверим, что все разделы удалены:
lsblk /dev/sdb
Следующим образом восстановим резервную копию на диске /dev/sdb с помощью следующей команды:
sudo dd if=disk-bak.img of=/dev/sdb
Наконец, убедимся, что раздел был создан на диске /dev/sdb:
lsblk /dev/sdb

11. Резервное копирование главной загрузочной записи с помощью команды dd
Главная загрузочная запись (MBR) находится в первом секторе загрузочного диска. Она хранит информацию о разделах диска. Мы можем использовать команду dd, как показано ниже, чтобы сделать ее резервную копию:
sudo dd if=/dev/sda of=mbr.img bs=512 count=1
Приведенная выше команда делает резервную копию первых 512 байт, то есть одного сектора.

Важно отметить, что приведенная выше команда должна быть выполнена на загрузочном диске.
12. Восстановление главной загрузочной записи с помощью команды dd
В предыдущем примере мы создали резервную копию главной загрузочной записи (MBR). Теперь восстановим ее на диске /dev/sdb с помощью следующей команды:
sudo dd if=mbr.img of=/dev/sdb

13. Копирование содержимого CD/DVD-привода с помощью команды dd
По аналогии с разделами и дисками, мы можем использовать команду dd для копирования содержимого CD или DVD-привода. Поэтому давайте воспользуемся следующей командой:
sudo dd if=/dev/cdrom of=alma-minimal.iso
В Linux привод CD/DVD представлен устройством /dev/cdrom. Поэтому мы используем его в качестве исходного файла.
Теперь давайте проверим, что содержимое диска было успешно скопировано, проверив его контрольную сумму командой:
sha256sum alma-minimal.iso

14. Создание загрузочного USB-накопителя с помощью команды dd
В предыдущем примере мы создали iso-образ Alma Linux. Теперь давайте используем его для создания загрузочного USB-накопителя:
sudo dd if=alma-minimal.iso of=/dev/sdb

Важно отметить, что приведенная выше команда должна быть выполнена с правильным USB-накопителем.
15. Как показать индикатор прогресса
По умолчанию команда dd не показывает прогресс при выполнении операции копирования. Однако мы можем отменить это поведение по умолчанию с помощью опции status.
Так что давайте используем опцию status=progress с командой dd, чтобы показать индикатор выполнения:
sudo dd if=alma-minimal.iso of=/dev/sdb status=progress

Вывод
В этой статье мы рассмотрели некоторые практические примеры использования команды dd. Опытные пользователи могут обращаться к этим примерам в повседневной жизни при работе с системами Linux. Однако при выполнении этих команд нужно быть очень осторожным. Ведь небольшая ошибка может привести к перезаписи содержимого всего диска.
Иногда при работе в интерфейсе командной строки Linux может потребоваться выполнение операции точного побитового копирования данных. Чаще всего это требуется для создания образов и резервных копий. Для этого можно воспользоваться утилитой dd, что означает data duplicator (дубликатор данных). И хотя она изначально не создавалась для функции резервного копирования, в данном контексте она оказывается очень полезной. В этом руководстве мы на нескольких простых примерах разберём, как она работает.
Содержание
- Синтаксис
- Примеры использования команды dd
- Изменение регистра текста
- Чтение и запись файлов и устройств
- Пропуск части входных данных
- Действия с выходными файлами
- Сокращение вывода в stderr
- Заключение
Синтаксис
Синтаксис команды следующий:
dd [ОПЦИИ]...
Вот список наиболее важных опций:
bs=РАЗМЕР_БЛОКА — считывать и записывать блоками указанного размера
cbs=bs=РАЗМЕР_БЛОКА — конвертировать данные блоками указанного размера
conv=ПАРАМЕТРЫ — конвертировать входной файл в соответствии с заданными параметрами (некоторые из них будут рассмотрены ниже, полный список можно посмотреть на соответствующей man-странице)
count=КОЛИЧЕСТВО — копировать только указанное количество блоков
ibs=РАЗМЕР_БЛОКА — считывать блоками указанного размера (по умолчанию 512 байт)
if=ФАЙЛ — считывать данные из файла, а не стандартного потока ввода
iflag=ПАРАМЕТРЫ — считывать данные в соответствии с заданными параметрами
obs=РАЗМЕР_БЛОКА — записывать блоками указанного размера (по умолчанию 512 байт)
of=ФАЙЛ — записывать данные в файл, а не стандартный поток вывода
oflag=ПАРАМЕТРЫ — считывать данные в соответствии с заданными параметрами
seek=КОЛИЧЕСТВО — пропустить заданное количество блоков размера obs в начале вывода
skip=КОЛИЧЕСТВО — пропустить заданное количество блоков размера ibs в начале ввода
Рассмотрим несколько примеров использования команды dd, таких как создание больших файлов для тестирования, создание образов и копий дисков.
Изменение регистра текста
Наиболее простой пример, на котором можно рассмотреть работу команды — скопировать текст с заменой регистра символов (большие буквы вместо маленьких или наоборот).
Допустим, у вас есть несколько строк текста, написанного в нижнем регистре, а вам нужно перевести его в верхний регистр. Для этого можно воспользоваться опцией conv с аргументом ucase:
dd conv=ucase

Здесь мы видим команду и введённый текст. Чтобы показать dd, что ввод текста завершён, мы воспользовались комбинацией клавиш Ctrl+D, и команда вывела следующий результат:

Введённый текст был переведён в верхний регистр, последние три строки — это статистика операции. Аналогичным образом можно перевести текст в нижний регистр.
Чтение и запись файлов и устройств
В предыдущем примере мы вводили текст в stdin (стандартный поток ввода). Однако, всегда можно использовать входные и выходные файлы. Чтобы указать имена входного и выходного файла, используются опции if и of, соответственно. Например, если вам нужно перевести в верхний регистр текст из файла file1 и записать его в файл file2, можно выполнить следующую команду:
dd if=file1 of=file2 conv=ucase
Командой dd также можно создавать файлы различных объемов, например для тестов. Следующая команда создаст файл объемом 1 ГБ заполненный случайными данными
dd if=/dev/urandom of=bigfile bs=1M count=1000

Или файл заполненный нулями
dd if=/dev/null of=bigfile bs=1M count=1000
В качестве аргументов можно указывать не только файлы, но и блочные устройства. А так как команда именно дублирует данные, а не копирует их по файлам, это открывает огромные возможности для резервного копирования и создания образов дисков.
Например, следующая команда полностью копирует диск /dev/sda на диск /dev/sdb:
dd if=/dev/sda of=/dev/sdb bs=4096 conv=noerror,sync
Аргумент noerror опции conv позволяет программе продолжать копирование даже при наличии ошибок, а sync задаёт использование синхронизированного ввода/вывода. Размер блока должен быть кратным 1 Кб (1024 байта), а выходной диск равен по объему входному или больше.
Аналогично можно создать образ CD или DVD, вместе с загрузочным сектором:
dd if=/dev/cdrom of=/mycd.iso
Опция -o loop команды mount позволяет смонтировать файл как обычное устройство. Так можно подключить созданный образ:
mount -o loop /mycd.iso /mnt/cd
Пропуск части входных данных
При необходимости можно задать команде пропустить несколько начальных байтов входных данных. Это осуществляется при помощи опции skip с целочисленным аргументом. Например, если значение этого аргумента N, то dd пропустит N блоков размера ibs. Это ещё одна опция команды, которая определяет число байтов, считываемых за раз (по умолчанию 512).
Если вам требуется пропустить первые 4 байта входного файла, нужно задать ibs равным 4, а аргумент skip равным 1. Таким образом при чтении файла команда пропустит один блок размером 4 байта.
dd if=file1 of=file2 ibs=4 skip=1
Сравним файлы командой grep
grep -v -f file1 file2

Видно, что часть текста при считывании файла file1 были пропущены, поэтому в файле file2 их нет.
Действия с выходными файлами
Чтобы команда работала только в том случае, если выходного файла ещё не существует, в качестве аргумента опции conv можно указать значение excl.
dd if=file1 of=file3 conv=excl
![]()
По умолчанию dd перезаписывает выходной файл, если он уже существует. Если требуется обновление с записью в конец файла, укажите значение append для опции oflag и значение notrunc для опции conv, например:
dd if=file1 of=file2 oflag=append conv=notrunc
При необходимости можно также отключить создание выходного файла, если такого файла не существует. Для этого используется аргумент nocreat опции conv:
dd if=file1 of=file10 oflag=append conv=nocreat
![]()
Сокращение вывода в stderr
Можно ограничить объём информации, выводимой в поток stderr, при помощи опции status. Например, если требуется сообщать только об ошибках, нужно указать эту опцию с аргументом none:
dd if=file1 of=file3 status=none
Другие возможные значения — noxfer, исключающее вывод конечной статистики, и progress, исключающее вывод текущей статистики.
Заключение
Рассмотренные примеры охватывают лишь небольшую долю задач системного администрирования, для которых может пригодиться команда dd.
Например, ее можно использовать для создания виртуальных файловых систем и резервного копирования целых дисков или системных разделов. Для получения более подробной информации о команде можно ознакомиться с ее man-страницей.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
I don’t know if this is useful to anyone, but if I found this page in my search, maybe it will help someone (other than the OP who hopefully solved his problem months ago).
ddrescue may be the best choice in this case, for data recovery (different from «fixing» the error/disk as the original question was worded), as Dennis suggested.
Alternatively, you could also mount the disk and copy the files. This is MUCH faster if there is lots of empty space, or if you only want some particular files. WARNING: done from a Linux machine, this loses all extended attributes, such as file permissions, so is a very bad choice for OS files, but tolerable for user files. Doing it from windows should preserve those, but might not handle errors smoothly, possibly making it go very slow.
Another option to actually «fix» the sectors, not just bypass them, is to reallocate the bad sectors. If you know the sector number (in your case, 11233976 assuming your block size in dd, and sector size are 512), just run this, and run again for each new bad sector you find:
hdparm –write-sector 11233976 –yes-i-know-what-i-am-doing /dev/sdb
WARNING: This will destroy the data on that sector. So be sure you really do know what you’re doing. If this sector can’t be read, overwriting it will stop the errors, but it will mean that sector will contain garbage, possibly corrupting an important file.
See this for more info: http://www.sjvs.nl/forcing-a-hard-disk-to-reallocate-bad-sectors/
And if your disk has a large number (thousands perhaps) of bad sectors (either seen as Current_Pending_Sector, Offline_Uncorrectable or Reallocated_Sector_Ct), or if it’s new and still on warranty, or if the number consistently goes up over time, then you should replace the disk anyway. Don’t let them tell you that reallocating fixes the disk. It only fixes the known bad sectors and consumes the sectors reserved for reallocation. If the disk is prone to developing more bad sectors, the problem will just keep coming back, each time corrupting some data.