Pre*_*soc 5 usb hard-drive data-recovery ddrescue
我的外部 USB 硬盘已损坏。当我将设备连接到电脑时,我可以访问文件系统大约一分钟。在此期间之后,磁盘继续旋转,但每个 io 操作都会超时。
为了挽救我想要使用的数据ddrescue,但由于设备每分钟都会停止工作,当我每次发生读取超时时不重置 USB 设备时,这不会恢复太多,因为最可能的原因是,设备再次挂断。有没有办法让 ddrescue 在发生读取超时时执行 shell 命令或类似命令?
无法通过SATA 连接外部硬盘,因为内部没有可访问的SATA 连接器。
小智 5
我知道没有人会读到这篇文章,所以我不会过多阐述。很遗憾,因为这是我发现唯一有效的方法。
问题:试图从有很多坏扇区的硬盘中挽救大量有价值的照片。当读取软件偶然发现坏扇区时,它会挂起(变得无响应),您唯一能做的就是拔掉 USB 插头。
尝试过的事情:(没用)
所有软件都承诺“不间断地跳过坏扇区”。错误的。
此外,这些工具不允许选择简历块。
未尝试过:DeepSpar Disk Imager(硬件,售价 3000 美元以上)。
寻求解决方案
ddrescue是一个复杂的程序,其中所有内容都是可配置的。它可以在 Linux 和 Windows(使用 Cygwin)上运行。教程。我无法运行 DDRescue-GUI(一些 XOpenDisplay 错误),除了 GUI 比命令行更简单之外。
事情尝试了 ddrescue。有些人提出了一些解决方法:
解决方案
具有虚拟机 (VirtualBox) 的主机。主机运行一个服务器,该服务器侦听附加/分离命令并将它们发送到虚拟机。
运行控制工作流的管理器脚本的 Windows 来宾 VM:启动/停止 ddrescue、向主机发送附加/分离命令以及向前移动映射文件中的位置。
Linux (Debian) VM 无法工作。分离后,VirtualBox 提示:“无法将 USB 设备连接到虚拟机”
####Script1 server.py runs in host####
import subprocess
from bottle import route, run
exe = "C:/Program Files/Oracle/VirtualBox/VBoxManage.exe"
vm = "Win7"
id = "54a7249b-930a-4d49-a679-9a7b8810adcc" # VBoxManage list usbhost
def execute(cmd):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
(output, err) = p.communicate()
p_status = p.wait()
res = output.decode("utf-8")
if "error" in res:
return "1"
else:
return "0"
return
@route('/attach')
def cmd1():
res = execute('"' + exe + '" controlvm ' + vm + " usbattach " + id)
return res
@route('/detach')
def cmd2():
res = execute('"' + exe + '" controlvm ' + vm + " usbdetach " + id)
return res
run(host='0.0.0.0', port=80)
Run Code Online (Sandbox Code Playgroud)
。
####Script2 manager.py runs in guest####
import requests
import subprocess
import time
import re
import os
def get_id(disk):
p = subprocess.Popen("wmic diskdrive get Index, Model", stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
p_status = p.wait()
res = output.decode("utf-8")
lines = res.splitlines()
id = ""
for line in lines:
if line.find(disk) > 1:
id = line[0]
return id
def check_disk(disk):
p = subprocess.Popen("wmic diskdrive get Model", stdout=subprocess.PIPE, shell=True)
(output, err) = p.communicate()
p_status = p.wait()
res = output.decode("utf-8")
if disk in res:
return 1
else:
return 0
def mod_disk(disk, cmd):
v=1 if cmd=='attach' else 0
for i in range(3):
response = requests.get('http://192.168.1.20/'+cmd)
res = response.content.decode("utf-8")
if "0" in res:
while True:
if(check_disk(disk)==v):
break
time.sleep(1)
print("[" + disk + " " + cmd + " wait]")
print("[" + disk + " " + cmd + " ok]")
break
time.sleep(3)
def dec2hex(n):
return "%X" % n
def hex2dec(s):
return int(s, 16)
def update_mapfile():
skip = 5000000 #5Mb
with open(mapfile, 'r') as file:
data = file.readlines()
line7 = data[6]
p = re.compile('^0x(.*?) ')
hval = p.findall(line7)[0]
dval = hex2dec(hval)
dval2 = dval + skip
hval2 = dec2hex(dval2)
line7b = re.sub(hval, hval2, line7)
data[6] = line7b
with open(mapfile, 'w') as file:
file.writelines(data)
############################
disk = "WD 3200AAJ"
mapfile = "E:/mapfile.log"
inpt = "/dev/sdb" if get_id(disk) == "1" else "/dev/sdc"
cmdl = 'c:/cygwin/bin/ddrescue.exe -v -d -n -O ' + inpt + ' E:/image.img E:/mapfile.log'
#Start ddrescue
proc = subprocess.Popen(cmdl, shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)
print("Start ddrescue")
time.sleep(60)
while True:
ft = os.path.getmtime(mapfile)
n = time.time()
if n-ft > 60:
#send sigterm
p = subprocess.Popen('taskkill /f /fi "imagename eq ddrescue.exe"', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
(output, err) = p.communicate()
p_status = p.wait()
print("send sigterm")
#detach HDD
mod_disk(disk, 'detach')
time.sleep(2)
print("detach HDD")
#update modfile
update_mapfile()
print("update modfile")
#attach HDD
mod_disk(disk, 'attach')
time.sleep(2)
print("attach HDD")
#restart ddrescue
inpt = "/dev/sdb" if get_id(disk) == "1" else "/dev/sdc"
cmdl = 'c:/cygwin/bin/ddrescue.exe -v -d -n -O ' + inpt + ' E:/image.img E:/mapfile.log'
proc = subprocess.Popen(cmdl, shell=True, stdin=None, stdout=None, stderr=None, close_fds=True)
print("restart ddrescue")
time.sleep(60)
Run Code Online (Sandbox Code Playgroud)
显然,您需要根据您的系统调整配置。
\n\n每当发生读取超时时,有没有办法让
\nddrescue执行 shell 命令等?
不,但您可以使用这些:
\n\n\n\n
-T interval
\n--timeout=interval
\n自上次成功读取后放弃之前允许的最长时间。默认为无穷大。[\xe2\x80\xa6]\n
-X n
\n--max-read-errors=n
\n放弃之前允许的最大读取错误数。默认为无穷大。如果遇到1多个读取错误,则退出并显示状态。n[\xe2\x80\xa6]
并与“shell 命令左右”一起ddrescue循环运行(mapfile 是必须的,因此可以恢复而不是重新启动)。ddrescue
我想在某些情况下这可能会有所帮助:
\n\n\n\n
-O
\n--reopen-on-error
\n在复制阶段遇到每个读取错误后关闭 infile,然后重新打开它。[\xe2\x80\xa6]
否则这个问题可能是:Hard Reset USB in Ubuntu 10.04
\n| 归档时间: |
|
| 查看次数: |
2316 次 |
| 最近记录: |