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