it-swarm-ru.tech

дд против кошки - дд еще актуален в наши дни?

Недавно я понял, что мы можем использовать cat столько же, сколько dd, и это на самом деле быстрее, чем dd

Я знаю, что dd был полезен при работе с лентами, где размер блока действительно имел значение в правильности, а не только в производительности. В наши дни, однако, бывают ситуации, когда dd может сделать то, что cat не может? (Здесь я бы посчитал разницу в производительности менее 20% несущественной.)

Конкретные примеры были бы хорошими!

129
kizzx2

По внешнему виду dd - это инструмент из операционной системы IBM, который сохранил свой внешний вид (передачу параметров), который выполняет некоторые очень редко используемые функции (например, EBCDIC для ASCII преобразования или обращение к порядку байтов ... в настоящее время это не является общей потребностью).

Я раньше думал что dd был быстрее для копирования больших блоков данных на тот же диск (из-за более эффективного использования буферизации), но это это не так , по крайней мере в современных системах Linux.

Я думаю, что некоторые параметры dd полезны при работе с лентами, где чтение действительно выполняется в блоках (драйверы ленты не скрывают блоки на носителе, как это делают драйверы дисков). Но я не знаю специфики.

dd может сделать одну вещь, которую нельзя (легко) сделать с помощью любого другого инструмента POSIX, - взять первые N байтов поток. Многие системы могут сделать это с помощью head -c 42, но head -c, хотя и часто встречается, отсутствует в POSIX (и сегодня недоступен, например, в OpenBSD). (tail -c - это POSIX.) Кроме того, даже там, где существует head -c, он может прочитать слишком много байтов из источника (потому что он использует внутреннюю буферизацию stdio), что является проблемой, если вы ' повторное чтение из специального файла, где только чтение имеет эффект. (Текущие GNU coreutils читают точное число с помощью head -c, но FreeBSD и NetBSD используют stdio.)

В более общем смысле, dd предоставляет интерфейс к базовому файловому API, который является уникальным среди инструментов Unix: только dd может перезаписывать или усекать файл в любой точке или поиск в файле. (Это уникальная способность dd, и она очень большая; как ни странно, dd наиболее известна тем, что могут делать другие инструменты.)

  • Большинство инструментов Unix перезаписывают свой выходной файл, то есть стирают его содержимое и запускают его с нуля. Это то, что происходит, когда вы используете перенаправление > в командной консоли.
  • Вы можете добавить содержимое файла с помощью перенаправления >> в командной консоли или с помощью tee -a.
  • Если вы хотите сократить файл, удалив все данные после определенного момента, это поддерживается базовым ядром и C API через truncate функция, но не предоставляется никаким инструментом командной строки кроме dd :

    dd if=/dev/null of=/file/to/truncate seek=1 bs=123456  # truncate file to 123456 bytes
    
  • Если вы хотите перезаписать данные в середине файла, опять же, это возможно в API-интерфейсе underyling путем открытия файла для записи без усечения (и вызова lseek) чтобы переместиться в нужную позицию при необходимости), но только dd может открыть файл без усечения или добавления, или поиск из командной консоли ( более сложный пример ).

    # zero out the second kB block in the file (i.e. bytes 1024 to 2047)
    dd if=/dev/zero of=/path/to/file bs=1024 seek=1 count=1 conv=notrunc
    

Итак ... Как системный инструмент, dd практически бесполезен. Как инструмент обработки текста (или двоичного файла), он весьма ценен!

167

Команда dd содержит множество опций, которые cat не может вместить. Возможно, в ваших случаях использования cat является подходящей заменой, но это не замена dd.

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

Эти опции dd делают его незаменимым для тонкой обработки данных, тогда как cat * может работать только с целыми файловыми объектами, устройствами или потоками.

* Как отметил Жиль в комментариях, можно комбинировать cat с другими инструментами, чтобы изолировать части чего-либо, но cat по-прежнему работает со всем объектом.

22
Caleb

Никто еще не упомянул, что вы можете использовать dd для создания разреженных файлов , хотя truncate также можно использовать для той же цели.

dd if=/dev/zero of=sparse-file bs=1 count=1 seek=10GB

Это почти мгновенно и создает произвольный большой файл, который можно использовать, например, в качестве петлевого файла:

loop=`losetup --show -f sparse-file`
mkfs.ext4 $loop
mkdir myloop
mount $loop myloop

Приятно то, что изначально он использует только один блок дискового пространства, а затем увеличивается только по мере необходимости (форматирование ext4 файла 10 ГБ в моей системе занимает 291 МБ). Используйте du, чтобы увидеть, сколько фактически места на диске используется - ls сообщает только о максимальном размере, до которого может увеличиться файл.

21
Lauritz V. Thaulow

Переопределение определенных сегментов жесткого диска чем-то - типичный пример. Например, вы можете удалить MBR с помощью этой команды:

dd if=/dev/zero of=/dev/sda bs=446 count=1

Также вы можете создавать пустые файлы с ним (скажем, для циклических образов дисков):

dd if=/dev/zero of=10mb.file bs=1024k count=10
10
XQYZ

dd очень полезно для резервного копирования загрузочного сектора жесткого диска или другого устройства хранения (dd if=/dev/sda of=boot_sector.bin bs=512 count=1), а затем переписать его (dd if=boot_sector.bin of=/dev/sda). Это также полезно для резервного копирования заголовков зашифрованных томов.

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

9
LawrenceC

У меня недавно была причина клонировать несколько разделов размером в несколько сотен гигабайт впервые в моей истории Linux (c.f cp -ar или rsync, которые служили мне много раз). Конечно, я обратился к dd, потому что все знают, что это то, что вы используете ... и был потрясен производительностью. Небольшое приближение к гуглу вскоре привело меня к ddrescue , который я уже использовал несколько раз и работает великолепно (намного быстрее, чем dd).

5
timday

Вот несколько трюков, которые я придумал за эти годы.

Вырежьте и вставьте в недружелюбный tash или неинтерактивный режим bash

Если вы находитесь в ситуации, когда EOF/^ D/^ F не обнаружен, вы можете использовать dd для передачи текстовых файлов на хост. Так как он остановит чтение после указанного количества байтов автоматически.

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

На самом деле, я даже создал пару двоичных файлов, кодируя их с помощью base64 и используя медленный, но надежный сценарий декодирования с использованием чистого bash base64.

dd of=textfile.txt bs=1 count=<size_of_data_in_paste_buffer>

Очень крутой трюк в том, что во время работы dd, если вы отправите ему сигнал USR1, он выдаст свое текущее состояние (считанные байты, байты в секунду ...)

Универсальный фильтр состояния пропускной способности

Я написал это, чтобы действовать как чистый фильтр прогресса bash для любой программы, которая генерирует данные через стандартный вывод. (Примечание: практически все что угодно будет генерировать данные через stdout - для программ, которые этого не делают, вы можете обмануть, если они не будут раздражать вас, используя/dev/stdout в качестве имени файла. Но идея в основном заключается в том, что каждый раз, когда вы получаете X количество байтов, печатные хеш-метки (как в старом школьном FTP, когда у вас включен хеш-режим)

(Примечание) Файл с прогрессом хромает, в основном это было доказательством концепции. Если бы я переделал это, я бы просто использовал переменную.

 dd bs=$BLKSZ of=${TMPFILE} 2>&1 \
                | grep --line-buffered -E '[[:digit:]]* bytes' \
                | awk '{ print $1 }' >> ${PROGRESS} &

 while [[ $(pidof dd) -gt 1 ]]; do

        # PROTIP: You can sleep partial seconds
        sleep .5

        # Force dd to update us on it's progress (which gets
        # redirected to $PROGRESS file.    
        pkill -USR1 dd
        local BYTES_THIS_CYCLE=$(tail -1 $PROGRESS)
        local XFER_BLKS=$(((BYTES_THIS_CYCLE-BYTES_LAST_CYCLE)/BLKSZ))

        if [ $XFER_BLKS -gt 0 ]; then
                printf "#%0.s" $(seq 0 $XFER_BLKS)
                BYTES_LAST_CYCLE=$BYTES_THIS_CYCLE
        fi
done

файлы фрагментов с использованием анонимных файловых дескрипторов оболочки

Вот чрезвычайно псевдокодовый пример того, как вы можете иметь подписанный tar-файл, который вы можете извлечь без ошибок, предоставляя ввод tar через анонимный дескриптор файла - без использования каких-либо файлов tmp для хранения частичных данных файла.

generate_hash() {
    echo "yay!"
}

# Create a tar file, generate a hash, append it to the end
tar -cf log.tar /var/log/* 2>/dev/null
TARFILE_SIZE=$(stat -f "%z" log.tar)
SIGNATURE=$(generate_hash log.tar)
echo $SIGNATURE >>log.tar

# Then, later, extract without getting an error..

tar xvf <(dd if=$OLDPWD/log.tar bs=1 count=${TARFILE_SIZE})

Я считаю, что дд невероятно полезен. И это только три примера, которые я могу придумать не покладая рук.

5
synthesizerpatel

Вы можете перенаправить некоторый выходной контент. Это особенно полезно, если вам нужно написать с помощью Sudo:

echo some_content | Sudo dd status=none of=output.txt

Помимо Sudo это эквивалентно:

echo some_content > output.txt

или к этому:

echo some_content | Sudo tee output.txt > /dev/null
5
Alexey