Утилита dd в Unix/Linux

dd (dataset definition) — утилита UNIX, служит для копирования, конвертации файлов, а так же — чтение данных. Название унаследовано от оператора DD (Dataset Definition) из языка JCL.

Поскольку в UNIX многие объекты (жёсткие/гибкие диски, COM/LPT-порты, оперативная память компьютера, память с кодом/данными каждого процесса) представлены в виде специальных файлов, спектр применения утилиты dd гораздо шире, чем кажется на первый взгляд. Регулярно возникает необходимость не просто скопировать файл или несколько файлов (для чего предназначена утилита cp), а скопировать первые n байт файла, пропустить m байт от начала, прочитать файл с дефектного носителя, транслировать содержимое файла в ASCII, «развернуть» порядок байтов в файле (Little-Endian vs. Big-Endian), просто скопировать очень большой файл или все вместе взятое. Для этой цели и служит dd.

Кроме всего прочего, данная утилита позволяет скопировать регионы из файлов «сырых» устройств, например, сделать резервную копию загрузочного сектора жёсткого диска, или прочитать фиксированные блоки данных из специальных файлов, таких, как /dev/zero или /dev/random.

Название утилиты dd иногда в шутку расшифровывают, как «disk destroyer», «data destroyer», «delete data» или «добей диск», так как утилита позволяет производить низкоуровневые операции на жёстких дисках — при малейшей ошибке (такой, как реверс параметров if и of) можно потерять часть данных на диске (или даже все данные). Есть и более «уважительное» прозвище — «disk duplicator», потому что на практике основное её применение — это копии, образы и бэкапы разделов.

Синтаксис утилиты:

$ dd if=путь_к_файлу of=куда_копировать другие_параметры

где:

  • путь_файлу — Путь к файлу, имеджу от куда будут взяты данные.
  • куда_копировать — Куда будут копироваться даные (флешка, диск, файл)
  • другие_параметры — Различные параметры использования.

Возможные параметры:

  • bs — Данная опция служит для указания размера блока (block size), который будет читать и писать данные за один раз. Например, можно указать 512, 1m, 8m. Рекомендую не использовать большие цифры, оптимально — это 4-8мб;
  • cbs — Данный параметр служит для того, чтобы указать сколько байт нужно записывать за один раз;
  • count — Данная опция указывает сколько копировать блоков, а размер блока задается с bs опцией;
  • conv — Опция служит чтобы преобразовать файл в соответствии с разделенными запятыми списком символов. Каждый символ может быть одним из следующих и представляет определенный тип преобразования: ascii, ebcdic, ibm, block, unblock, lcase, nocreat, excl, notrunc, ucase, swab, noerror, sync, fdatasync, fsync. Описание данных типов, будет ниже.
  • ibs — Данная опция указывает на то, сколько необходимо считать байт за раз (Дефолтное значение — 512 байт);
  • obs — Данная опция указывает на то, сколько необходимо записать байт за раз (Дефолтное значение — 512 байт);
  • seek — Данная опция указывает на то, сколько необходимо пропустить количество байт (obs-size блоков) в начале вывода;
  • skip — Данная опция указывает на то, сколько необходимо пропустить количество байт (ibs-size блоков) в начале ввода;
  • status — Указывает насколько подробным нужно сделать вывод;
  • iflag, oflag — Позволяет задать дополнительные флаги работы для устройства ввода и вывода, основные из них: nocache, nofollow.

Параметры conv:

  • ascii — Преобразование с EBCDIC в ASCII.
  • ebcdic — Преобразование с ASCII to EBCDIC.
  • ibm — Преобразование с ASCII в алтернативный EBCDIC.
  • blockpad — Завершение новой строкой записи с пробелами в cbs-size.
  • unblock — Заменить конечные пробелы в записях размера cbs новой строкой.
  • lcase — Изменить верхний регистр на нижний регистрe.
  • nocreat — Не создавайть выходной файл.
  • excl — Ошибка, если выходной файл уже существует.
  • notrunc — Не обрезать выходной файл.
  • ucase — Заменить нижний регистр на верхний.
  • swab — Поменять местами каждую пару входных байтов.
  • noerror — Продолжить после ошибок чтения.
  • sync — Дополняет каждый входной блок значениями NUL до размера ibs; при использовании с block или unblock, используеться блок с пробелами, а не NUL.
  • fdatasync — Физически записывает данные выходного файла до окончания процесса.
  • fsync — Аналогично, но также пишуться метаданные.

Параметры для iflag, oflag:

  • append — append mode (имеет смысл только для вывода; conv=notrunc предложение).
  • direct — Использует прямой ввод/вывод (I/O) для данных.
  • directory — Выдает фейл, если используете каталог.
  • dsync — Использовать синхронизированность I/O для данных.
  • sync — Точно так же, но и для метаданных.
  • fullblock — Накапливает полные блоки ввода (iflag только).
  • nonblock — Использует неблокирующий ввод/вывод (I/O).
  • noatime — Не обновляет время доступа (зачастую используеться).
  • noctty — Не назначает управляющий терминал из файла.
  • nofollow — Не переходит по символическим ссылкам.

Для count, seek, skip, bs, cbs, ibs, obs можно использовать слудующую размерность:

  • c=4
  • w=8
  • b=512
  • kB=1000
  • K=1024
  • MB=1000*1000
  • M=1024*1024
  • xM=M
  • GB=1000*1000*1000
  • G=1024*1024*1024

Примеры утилиты dd в Unix/Linux

Начнем с самого простого — получить помощь:

$ dd --help

Замечаение: в Unix (например на MacOS) может не работать, по этому — имееться следующее решение:

$ man dd

Узнать версию можно вот так:

$ dd --version

Замечание: Работат на Linux. На Unix, возможно не будет работать.

-=== ПРИМЕР 1 ===-

Чтобы записать образ на флешку или диск, можно использовать:

$ sudo dd if=2019-04-08-raspbian-stretch-lite.img of=/dev/disk3 bs=1m

-=== ПРИМЕР 2 ===-

Если необходимо скопировать диск на другой, например, можно сделать это следующим образом:

# dd if=/dev/disk2 of=/dev/disk3 bs=4096 conv=noerror,sync

-=== ПРИМЕР 3 ===-

Так же, иногда полезно сжать данные и записать их куда-то (Проверял только с gzip, bzip2). Например, необходимо сделать бэкап. Используем bzip2 сжатие:

# dd if =/dev/disk2 | bzip2 disk2.img.gz

Или, используем gzip:

$ sudo dd if=/dev/disk3 | gzip -c > /Users/captain/raspberrypi.img.gz
Password:
250347520+0 records in
250347520+0 records out
128177930240 bytes transferred in 6767.601942 secs (18939933 bytes/sec)

Не забываем комбинировать опции (можно использовать в этом случае: bs=8m, status=progress, conv=fsync)

PS: для рестора можно заюзать:

# gzip -dc /Users/captain/raspberrypi.img.gz | dd of=/dev/disk2

Можно удаленно создать бэкап, например:

# ssh your_ssh_user@your_ssh_host "dd if=/dev/disk2 | gzip -1 -" | dd of=your_backup_here.gz

Как другое решение, можно делать бекап по указанному времени и бэкапить его по сети. Например:

# dd if=/dev/disk2 | ssh your_ssh_user@your_ssh_host "dd of=/Users/captain/raspberrypi.img.gz".

PS: Стоит добавить SSH ключи ssh будет работать такая схема

-=== ПРИМЕР 4 ===-

Чтобы отформатировать накопитель низкоуровневым способом используя dd, пример выглядит вот так:

# dd if=/dev/zero of=/dev/disk2

PS: Можно обнулить только определенное количество байт, например:

# dd if=/dev/zero of=/home/captain/the_file_here bs=512 count=1 conv=notrunc

Проверить можно тем же dd, но преобразовав данные в hex:

# dd if=/dev/disk2 | hexdump -C

Должны быть 0. Или, можно проверить еще другим методом:

# dd if=/dev/disk2 | hexdump -C | grep [^00] 

Можно для тестирования, взять и скопировать 10 ГБ нулей и перенаправить их в /dev/null (в никуда):

# dd if=/dev/zero of=/dev/null bs=100M count=100

Уничтожить суперблок можно:

# dd if=/dev/zero count=1 bs=1024 seek=1 of=/dev/disk2 

или еще один солюшен:

# dd if=/dev/zero count=1 bs=4096 seek=0 of=/dev/disk2 

Чтобы очистить первые 113 МБ раздела:

# dd if=/dev/zero of=/dev/disk2\
 bs=113m count=1

-=== ПРИМЕР 5 ===-

MBR расположена в первых 512 байтах жесткого диска, и состоит из таблицы разделов, загрузчика и пары дополнительных байт. Иногда, ее приходится бекапить, восстанавливать и т.д. Бекап можно сделать так:

# dd if=/dev/disk2 of=just_mbr_in.img bs=512 count=1

Чтобы восстановить, используем:

# dd if=just_mbr_in.img of=/dev/disk2

Если нужно сделать резервное копирование загрузочных данных MBR, исключая таблицу разделов, то пример вот:

# dd if=/dev/disk2 of=/tmp/disk2_mbr2.img bs=446 count=1

Вернуть назад можно так:

# dd if=/home/test/just_mbr_in.img of=/dev/disk2 bs=446 count=1

Cкопировать MBR на дискету:

# dd if=/dev/disk2 of=/dev/fd0 bs=512 count=1

Просмотр MBR-а через dd утилиту:

# dd if=/dev/disk2 count=1 | hexdump -C

-=== ПРИМЕР 6 ===-

При помощи dd можно генерировать файлы, а затем использовать их как контейнеры других файловых систем даже в зашифрованном виде. Технология следующая:
С помощью dd создается файл, забитый нулями (случайными числами забивать не рационально: долго и бессмысленно):

# dd if=/dev/zero of=your_image_is.crypted bs=1M count=1000

Заполнить диск рандомными значениями:

# dd if=/dev/random of=/dev/disk2

Затереть файл\диск n-раз, можно так (в моем случаее, будет перезапись 20 раз):

# for i in {1..20};do dd if=/dev/random of=/dev/disk2; done

-=== ПРИМЕР 7 ===-

Создаем ISO из CD/DVD ROM-а на локальное устройство (файл на вашем диске):

# dd if=/dev/cdrom of=/your_image_from_cdrom.iso

Создать DVD образы раздела (полезно для резервного копирования):

# dd if=/dev/disk2 of=/your_disk2_1.img\
 bs=4M count=4430
# dd if=/dev/disk2 of=/your_disk2_2.img\
 bs=4M count=8860
[...]

После такого копирования, можно развернуть все назад следующим образом:

# dd if=/your_disk2_1.img of=/dev/disk2\
 bs=8M
# dd if=/your_disk2_2.img of=/dev/disk2\
 seek=4430 bs=8M
# dd if=/your_disk2_3.img of=/dev/disk2\
 seek=8860 bs=8M

Создать ISO из флопика можно вот так:

# dd if=/dev/fd0  of=~/floppy_here.img

-=== ПРИМЕР 8 ===-

Преобразовать формат данных файла( пример с EBCDIC в ASCII):

# dd if=textfile.ebcdic of=textfile.ascii conv=ascii

Преобразовать формат данных файла( пример с ASCII в EBCDIC):

# dd if=textfile.ascii of=textfile.ebcdic conv=ebcdic

-=== ПРИМЕР 9 ===-

Например у вас есть файл с текстом:

# cat file_with_lowercase.txt
test dd convert

Если нужно сконвертировать содержимое файл в верхний регистр:

# dd if=~/file_with_lowercase.txt of=~/file_with_uppercase.txt conv=ucase

Еще пример:

# ls -l | dd conv=ucase

Если нужно сконвертировать содержимое файла в нижний регистр:

# dd if=~/file_with_uppercase.txt of=~/file_with_lowercase.txt conv=lcase

-=== ПРИМЕР 10 ===-

Для просмотра вашей виртуальной памяти служит команда:

# dd if=/proc/kcore | hexdump -C | less

-=== ПРИМЕР 11 ===-

Чтобы проверить какие файловые системы установлены, выполните:

# dd if=/proc/filesystems | hexdump -C | less

-=== ПРИМЕР 12 ===-

Проверить все загруженные модули с помощью dd:

# dd if=/proc/kallsyms | hexdump -C | less

-=== ПРИМЕР 13 ===-

Для посмотра таблицы прерываний, есть команда:

# dd if=/proc/interrupts | hexdump -C | less

-=== ПРИМЕР 14 ===-

Проверить сколько секунд работала система:

# dd if=/proc/uptime | hexdump -C | less

-=== ПРИМЕР 15 ===-

Чтобы проверить разделы и так же, их размеры (в кб), используем:

# dd if=/proc/partitions | hexdump -C | less

-=== ПРИМЕР 16 ===-

Вывод статистики памяти:

# dd if=/proc/meminfo | hexdump -C | less

-=== ПРИМЕР 17 ===-

Хороший способ проверить наличие бэдов на устройстве с командой dd:

# dd if=/dev/disk2 of=/dev/null bs=1m 

-=== ПРИМЕР 17 ===-

Так же, можно с данной утилитой проверить файл на вирусы (но нужен для этого, нужно установить ClamAV):

# dd if=/home/captain/your_file_for_checking.gz | clamscan -

Ссылка на ClamAV:

Установка ClamAV на Debian/Ubuntu/ Linux Mint

Установка ClamAV на RedHat/Centos/Fedora

-=== ПРИМЕР 18 ===-

Тестируем скорость чтения/записи жестких дисков:

# dd if=/home/your_big_file_here of=/dev/null
# dd if=/dev/zero of=/home/your_big_file_here\
bs=1024 count=1000000

-=== ПРИМЕР 19 ===-

Вывести файл на стандартный вывод можно вот так:

# dd if=/home/your_file_here

-=== ПРИМЕР 20 ===-

Нашел еще пример, с которым можно выполнить поиск какой-то строки по всему разделу (Даже если наложена секьюрити), то можно использовать LiveCD и загрузиться с ним и выполнить:

# dd if=/dev/disk2 bs=16065 | hexdump -C\
 | grep 'search text string here'

-=== ПРИМЕР 21 ===-

Чтобы считать BIOS, выполните:

# dd if=/dev/mem bs=1k skip=768 count=256 \
2>/dev/null | strings -n 8

-=== ПРИМЕР 22 ===-

Нашел забавный пример:

# echo -n "hello man" | dd cbs=1 \
> conv=unblock 2> /dev/null
h
e
l
l
o

m
a
n

-=== ПРИМЕР 23 ===-

Убрать/проигнорировать первые 111 байтов стандартного ввода:

# dd ibs= 111 skip=1

-=== ПРИМЕР 24 ===-

Делаем быстрое резервное копирование по сети с использованием Netcat:

# dd if=/dev/disk2 | nc -l 10001 
nc $system_to_backup_IP 10001 | dd\
 of=sysbackupsda.img 

-=== ПРИМЕР 25 ===-

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

# dd if=/dev/zero of=tmpswap bs=1k\
 count=1000000
# chmod 600 tmpswap
# mkswap tmpswap
# swapon tmpswap

-=== ПРИМЕР 26 ===-

Определите скорость последовательного ввода-вывода вашего привода. Чтение 1 ГБ файла:

# dd if=/dev/disk2 of=/dev/null bs=1024k \
count=1024

-=== ПРИМЕР 27 ===-

Можно добавить прогресс бар, например:

# dd bs=4M if=2019-04-08-raspbian-stretch-lite.img | pv | of=/dev/disk3 conv=fsync

Или:

# sudo dd if=2019-04-08-raspbian-stretch-lite.img of=/dev/disk3 bs=1m status=progress conv=fsync

На этом у меня все, статья «Утилита dd в Unix/Linux» завершена.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.