Мужчина 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=').