Другой подход, поэтому другой ответ от меня.
Вы можете использовать ddrescue
для поиска нулей. Используйте --generate-mode
.
Когда ddrescue
вызывается с --generate-mode
он работает в "режиме генерации", который отличается от "режима восстановления" по умолчанию. То есть, если вы используете --generate-mode
, ddrescue
ничего не спасет. Он только пытается сгенерировать mapfile
для последующего использования.
[...]
В некоторых случаях ddrescue
может сгенерировать приблизительный mapfile
из infile
и (частичной) копии в outfile
, что почти так же хорошо, как точный mapfile
. Это можно сделать, просто предполагая, что сектора, содержащие все нули, не были спасены.
[...]
ddrescue --generate-mode infile outfile mapfile
(источник)
Давайте предположим, что ваш файл outfile
от предыдущего запуска ddrescue
Мы не можем использовать его как infile
(поскольку ddrescue
отказывается работать, когда infile
и outfile
- это один и тот же файл), нам нужен фиктивный файл, подойдет /dev/zero
. Чтобы найти каждый ноль, вам нужно -b 1
. Это команда (mapfile
не должен существовать):
ddrescue -b 1 --generate-mode /dev/zero file mapfile
Каждая запись с ?
в списке блоков данных внутри mapfile
означает блок нулей (при -b 1
один ноль также является блоком). Смотрите структуру файла карты для ddrescue
. Затем вы можете получить информацию из mapfile
.
Например, следующая команда даст вам длину (шестнадцатеричное, в байтах из-за -b 1
) наибольшего блока нулей (пустой вывод означает, что его не было):
grep '0x.*0x.*[?]' mapfile | awk -F ' ' '{print $2}' | sort -ru | head -n 1
Чтобы ускорить процесс, вы можете использовать больший размер блока (-b
), но тогда блоки нулей, начинающиеся в одном блоке и заканчивающиеся в следующем, могут остаться незамеченными, даже если они немного длиннее выбранного размера блока; их смещение становится важным.
Чтобы не пропустить ни одного отрезка нулей длиной N
или более, вам необходим размер блока не более M=$(((N+1)/2))
байтов (например, не более 5
для N=10
, 6
для N=11
) Команда
ddrescue -b "$M" --generate-mode /dev/zero file mapfile
сгенерирует mapfile где каждая строка с ?
в списке блоков данных подразумевается не менее M
нулей (с правым смещением), но каждый отрезок из N
нулей (независимо от его смещения) будет генерировать такую линию наверняка. Поскольку два блока из M
имеют по меньшей мере N
, применяются следующие соображения:
Принимая строки с ?
из списка блоков данных,
- если длина (второй столбец в
mapfile
, помните, что единицей является M
) равна 0x2
или больше, тогда у вас есть N
или более нулей в этой позиции;
- если длина равна
0x1
то вам следует продолжить исследование, если вокруг этой позиции есть хотя бы N
нулей;
- если такой строки нет, то в файле наверняка нет натяжения
N
нулей.
На самом деле они всегда будут кратны 512 байтам и всегда начинаются с адреса 512 байт.
В этом случае
ddrescue -b 512 --generate-mode /dev/zero file mapfile
найдет и сопоставит их всех.