我目前正在努力从即将耗尽的硬盘上拯救一个非常大的文件(点击声音)。读取失败的原因是少数有缺陷的扇区。
由于我可以检索的备份太旧,我的第一个计划是将文件从那里取出即使损坏的数据。PhotoRec
事实证明这是这项工作的理想选择,因为它确实成功地恢复了所有的文件。 (testdisk
这是一次史诗般的失败,因为它只会切断检测到错误的文件)
将(部分损坏的)文件检索到完整的目标 HDD 上后,接下来要采取的步骤是:
- 使用
hdparm --read-sector <device>
其输出并创建二进制数据文件 - 使用这些中的有效数据使用十六进制编辑器(如
Okteta
.
事实上,原始读取例程hdparm
(我用过v9.43) ( --read-sector
)可以确信从那个错误柱面上的(几个)坏扇区读取数据,但只给了我一个真实的ASCII码文件。我不知道有什么办法直接地将输出获取到二进制文件以执行上述第二步。此外,输出文件中的所有单词都是字节交换(Linux 上为 x86-32;v9.45 中修复,参见这个较旧的条目在错误跟踪器中)。
幸运的是,有一种方法可以让它在 v9.43 及更早版本中工作,通过使用hdparm
's--verbose
选项,该选项(在行中incoming_data
)将允许十六进制值完全按照读取的方式获得输出,正确的字节顺序!
这就是我到目前为止的想法,读取从 5000 开始的 50 个扇区:
i=0
while [[ $((i++)) -lt 50 ]]; do
sudo hdparm --verbose --read-sector $((5000+i)) /dev/sdb 2>&1 |
grep 'incoming_data' | cut -f2- -d: | sed 's/^ //' |
tee -a ascdata1_nl
done
tr '\n' ' ' < ascdata1_nl > ascdata1
警告:第一个文件ascdata1_nl
仍然包含新队人物。循环完成后,将换行符转换为空格后,ascdata1
现在将包含所需的值。现在逐字节写入 .bin 文件:
while read -d ' ' hexbyte; do printf "\x$hexbyte" | tee -a bindata.bin; done < ascdata1
结果将是一个真正的二进制文件,它可以(例如使用“Okteta”)用于替换文件中的(错误的)归零区域。
简短回答:有用那样。
不过,这个过程对我来说似乎有点过于复杂(?)。
有没有更简单的方法从“十六进制”转储中获取二进制文件--read-sector
?
- 使用
perl
,我确信可以省略--verbose
中的选项,因为/会做得很好。 (只是我没能用 byte 做到这一点hdparm
pack()
unpack()
对) dd conv=swab
:我也dd
尝试了这个选项,不幸的是,它只会交换半字节,变成a6b8 d6b7
(无用)6a8b 6d7b
。
答案1
假设你有 GNU sed,你可以尝试(没有真正测试过):
hdparm --read-sector $SECTOR /dev/sdb | \
sed -r -e "0,/succeeded/d" -e 's/(\S\S)(\S\S)/\2\1/g' | \
xxd -r -p >> bindata.bin
该sed
调用删除该行之前的所有内容succeeded
,然后对输出进行字节交换。该xxd -r -p
调用将纯十六进制代码转换为二进制数据。