I had a disk with a lot of surface errors that I used until a couple days ago when I got my new ssd. I want to know how I could completely copy over my home partition but ignore all errors while doing so, as it probably has a few hundred bad clusters in the beginning and it would literally take hours just clicking "ignore" on gparted. Please guys, I have like 85gb in there that would be an absolute pain to recreate or manually copy all files over and correct the permissions of.
3 Answers
A. To copy the files into a "flat" directory
If it is possible for the script to create at least a file list, but it should ignore the problems that might occur in copying them, it should work.
In case of duplicates, it will save the duplicates as duplicate_1_<filename>
, duplicate_2_` etc.
I used:
try
<copy_command>
except Exception
pass
Which covers the widest possible range of errors.
The script:
#!/usr/bin/env python3
import shutil
import os
sourcedir = "/path/to/source"
dest_dir = "/path/to/destination"
for root, dirs, files in os.walk(sourcedir):
for name in files:
subject = root+"/"+name
n = 1; name_orig = name
while os.path.exists(dest_dir+"/"+name):
name = "duplicate_"+str(n)+"_"+name_orig
n = n+1
try:
newfile = dest_dir+"/"+name
shutil.copy(subject, newfile)
except Exception:
pass
Copy it into an empty file, save it as giveit_ashot.py
and set the sourcedir and destination.
Run it by:
python3 /path/to/giveit_ashot.py
B. If the directory structure is important
then use the script below, it first tries to (re-)create the directories (top- down), then copies the files into the structure as much as possible. Again: it must at least be possible to create a file / directory list.
#!/usr/bin/env python3
import shutil
import os
sourcedir = "/path/to/source"
dest_dir = "/path/to/destination"
dirdata = []
filedata = []
for root, dirs, files in os.walk(sourcedir):
for dir in dirs:
absolute = root+"/"+dir
relative = absolute.replace(sourcedir, "")
dirdata.append([absolute, dest_dir+relative, len(absolute.split("/"))])
for file in files:
abs_file = root+"/"+file
rel_file = abs_file.replace(sourcedir, "") # source
filedata.append((abs_file, dest_dir+rel_file)) # destination
dirdata.sort(key=lambda x: x[2])
for item in dirdata:
try:
if not os.path.exists(item[1]):
os.mkdir(item[1])
except Exception:
pass
for item in filedata:
try:
shutil.copy(item[0], item[1])
except Exception:
pass
-
thanks. I didn't use the script and just used gparted and worked through all the errors but you deserve it for all the work you put into the script Sep 20, 2014 at 15:33
-
@sbergeron That is nice of you! I think it would have worked, I created some "impossible" files and directories, which were passed as I expected. Sep 20, 2014 at 15:44
gparted
suggest you're creating/formatting the partition. Not the one you have your home, I expect.
If the partition is already created, try to format with:
mkfs.ext4 -c /dev/sdXX
Make sure to put the right /dev/sdXX
.
If you're trying to copy from a bad partition to a good one, I don't know how cp
would behave in the face of IO errors.
-
I know it would have i/o errors, basically what I'm trying to do is get as much of my data off the bad disk in one piece, unaltered, as I can Sep 18, 2014 at 19:29
-
and cp would work, but it would have to be run as root so it would change the permissions of everything and really screw me up as I need to copy over stuff like my home partition and such Sep 18, 2014 at 19:30
You have to take different measures for
- fix bad blocks (some filesystems, like ext4 and ext3 allow this, info at
man e2fsck
) - copying ignoring errors (your initial question), e.g. with
rsync -a --ignore-errors /path/to/mountpoint/of/broken/device/ /path/to/folder/on/working/device/
A long shot remark: You might want to create an image of the partition with dd
before you overwrite it or throw the disk away (new recovery tools might come up in some time and get more data out of the disk than current and the tips (mine included) you get to restore the files might just be wrong), e.g. do sudo dd if=/dev/sdxY | pigz -p 8 | sudo tee /path/to/a/file/on/a/working/disk.img.gz
for a compressed image.