[Перевод] Бесполезность dd

smd2ghd-teeap7v5ud9hathlaaq.jpeg

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

tl; dr: Команда dd умеет читать и записывать диски, но не обладает какими-либо «низкоуровневыми возможностями работы с вводом-выводом», делающими её использование более предпочтительным в сравнении с другими утилитами командной строки. Подобно cat, вы должны использовать её там, где это имеет смысл, например, чтобы воспользоваться широким спектром опций, а не стараться из страха и суеверия убеждать себя, что все относящиеся к диску команды начинаются и заканчиваются dd.

Если вы когда-либо пользовались dd, то, вероятно, использовали её чтобы прочитать или записать образ диска:

# Запись myfile.iso на USB-накопитель
dd if=myfile.iso of=/dev/sdb bs=1M

Использование dd в данной ситуации настолько распространено, что она могла бы быть провозглашена волшебным привратником raw-устройств. Как прочитать с raw-устройства? Используйте dd. Хотите записать на raw-устройстви? Используйте dd.

Это убеждение добавляет ненужную сложность простым командам. Как объединить dd с gzip? Как использовать pv, если источник — raw-устройство? Как использовать dd через ssh?

Люди придумывают остроумные способы вставить dd в начало и конец конвейеров.
dd if=/dev/sda | gzip > image.gz, — пишут они. — dd if=/dev/sda | pv | dd of=/dev/sdb.

Использование dd в обоих случаях не является целесообразным. Это просто суеверное заклинание, направленное на защиту данных. Вы можете увидеть, насколько это глупо, заменив dd функционально эквивалентным cat: cat /dev/sda | pv | cat > /dev/sdb

Дело в том, что dd не является инструментом для записи на диск. Ни одна из букв «d» не означает «disk», «drive» или «device». Она не поддерживает «низкоуровневое» чтение или запись. Она не имеет никакой особой власти над каким-либо устройством.

dd просто читает и пишет файлы.

В UNIX, как говорится, всё есть файл. Это включает в себя и raw-диски. Поскольку raw-диски — это файлы и dd может быть использована для копирования файлов, dd применяется для копирования raw-дисков.

Но знаете ли вы что ещё может читать и писать файлы? Всё:

# Запись myfile.iso на USB-накопитель
cp myfile.iso /dev/sdb

# Копирование cdrom в .iso файл
cat /dev/cdrom > myfile.iso

# Создание сжатого образа gzip
gzip -9 < /dev/sdb > /tmp/myimage.gz

dd пользуется тем же интерфейсом, что и эти команды и не является ни более безопасной, ни более надёжной.

В конечном итоге dd может выполнять задачу даже хуже. По спецификации дефолтный размер блока — 512 байт и он не должен был меняться десятилетиями. Сегодня такой крошечный размер по умолчанию привязывает его к CPU. Скрипт, в котором не указан размер блока, очень неэффективен. И любой скрипт, использующий актуальное оптимальное значение, может со временем постепенно устареть или оказаться устаревшим, если его откуда-то скопировали.

Между тем, cat может свободно выбирать размер буфера, более подходящий в современной системе, а его размер в GNU cat неуклонно рос рос с 512 байт в 1991 до 131072 байт в 2014 (Примечание переводчика: 262144 байт в 2024) году. src/ioblksize.h в исходном коде coreutils содержит тесты, поддерживающие этот выбор.

Однако всё это совсем не означает, что dd нужно категорически избегать! Причина, по которой люди стали использовать её в первую очередь, состоит в том, что dd делает именно то, что ей говорят: не больше и не меньше.

Если в алиасе указан параметр -a, cp может попытаться создать новое блочное устройство вместо копирования данных файла. Если использовать gzip без перенаправления, он может попытаться оказаться полезным и пропустит файл, являющийся простым и обычным. И никто из них не выведет обнадёживающий статус в процессе или после копирования.

У dd, между тем, есть единственная задача *: копировать данные с одного места в другое. Её не волнуют файлы, аттрибуты безопасности или удобство пользователя. dd не будет пытаться угадать ваши намерения, основываясь на наличии оконечных слешей или типов файлов.

Однако, когда это становится неудобно, например, в комбинации с другими инструментами, уже читающими или пишущими файлы, не стоит чувствовать себя виноватым за то, что вы целиком и полностью отказались от dd.

Это вовсе не означает, что я считаю dd переоценённым! Au contraire! Это один из моих любимых инструментов Unix!

dd — это швейцарский армейский нож для системных вызовов open, read, write и seek. Эта команда уникальна своей способностью выполнять seeks и reads определённой длины, что позволяет создавать целый мир shell-скриптов, которые не имеют никакого отношения к shell-скриптам. Хотите имитировать lseek+execve? Используйте dd! Хотите открыть файл с помощью O_SYNC? Используйте dd! Хотите прочитать группы трёхбайтных пикселей из файла PPM? Используйте dd!

Это гибкий, уникальный и полезный инструмент, и он мне нравится. Единственное, что меня смущает, так это что слишком часто этот замечательный инструмент низводят до уровня его самой общей и наименее интересной способности и неуместно хвалят за это: простое копирование файла от начала и до конца.

* На самом деле dd выполняет две задачи: преобразование и копирование. В посте на comp.unix.misc (ошибочно) утверждалось, что предполагаемое имя «cc» было занято компилятором C, так что буквы были смещены таким же образом, каким Window System в итоге получила название X. Но более вероятное объяснение дали здесь в обсуждении Paweł и Bruce (Примечание переводчика: речь про комментарии к оригинальному посту): название, синтаксис и назначение почти идентичны команде JCL «Dataset Definition», встречавшейся в мейнфреймах IBM 1960-х годов.

© Habrahabr.ru