Можно ли использовать dd для обычных небольших файлов?

Можно ли использовать dd для обычных небольших файлов?

Мужчина dd:

dd - конвертировать и копировать файл

Я склоняюсь к использованию dd. Странно, что после копирования 1 байта текстовый файл становится намного меньше:

$ block_size=1; device_to_edit=/media/ramdrive/a; device_from=/media/ramdrive/b; echo "aaaaaaaaaa">$device_to_edit; echo "bbbbbbbbbb">$device_from; cat $device_to_edit; cat $device_from; dd if=$device_from of=$device_to_edit count=1 seek=2 skip=2 bs=$block_size; cat $device_to_edit
aaaaaaaaaa
bbbbbbbbbb
1+0 records in
1+0 records out
1 byte copied, 0,000156688 s, 6,4 kB/s
aab

Там говорилось 1 byte copied, почему пропал конец файла?

Добавлен:

Как и предполагалось в комментарии, conv=notruncисправляет это. Но из man:

conv=CONVS преобразовать файл в соответствии со списком символов, разделенных запятыми

Я не хотел конвертировать файл. Читая о копировании блочных устройств, я не видел этого операнда. Всегда ли он нужен, когда не все файлы (например, один блок размером 512 байт в /dev/sdb: USB disk) изменяются?

решение1

Вот что вы делаете:

block_size=1; 
dd ... count=1 seek=2 skip=2 bs=$block_size; 

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

$ echo abcdefgh > test1
$ echo 12345678 > test2
$ dd count=1 bs=1 skip=2 seek=2 if=test1 of=test2
1+0 records in
1+0 records out
1 byte copied, 0.000179375 s, 5.6 kB/s
$ cat test2; echo
12c

В имеющейся у меня странице руководства GNU об этом явно не говорится, ноописание POSIX делает:

of=file
Укажите выходной путь; [...] Если seek=exprуказано , но conv=notruncне указано , то результатом копирования будет сохранение блоков в выходном файле, по которым выполняется поиск dd, но никакая другая часть выходного файла не будет сохранена. (Если размер файла поиска плюс размер входного файла меньше предыдущего размера выходного файла, выходной файл будет укорочен копией.[...])

Чтобы этого не произошло, добавьте conv=notruncопцию:

notrunc
не обрезать выходной файл

$ echo 12345678 > test2
$ dd conv=notrunc count=1 bs=1 skip=2 seek=2 if=test1 of=test2
1+0 records in
1+0 records out
1 byte copied, 0.00019385 s, 5.2 kB/s
$ cat test2
12c45678

notruncне изменяет данные, которые фактически копируются, поэтому это не «преобразование» в этом смысле, хотя оно и воспринимается как флаг для conv.

Обратите внимание, что если count=задано, ddвыполняется ровно столько read()вызовов, что означает, что если вы считываете данные с устройства, которое может выполнять короткие операции чтения, объем фактически считанных данных не будет countв раз больше bs.

решение2

Следовало бы просмотреть полную документацию man dd:

Full documentation at: <https://www.gnu.org/software/coreutils/dd>
       or available locally via: info '(coreutils) dd invocation'

'of=FILE' Запись в ФАЙЛ вместо стандартного вывода. Если не указано 'conv=notrunc', 'dd' обрезает ФАЙЛ до нуля байтов (или размера, указанного с помощью 'seek=').

Связанный контент