As mentioned in comments, GNU
ddrescue is a way better tool for this use case. Let me answer your explicit questions about
I'd like to know, what
dd does when it encounters errors
It exits, unless
conv=noerror was given, which makes the tool ignore input errors. Let's suppose
noerror was given and an input error occurred. Then
Does it just skip the sector and writes nothing? Or does it replace the data that was previously on the target drive with 0s?
It depends whether or not you used
conv=sync. If you do,
dd will pad every input block to the size of the
ibs= buffer, appending null bytes. I guess if
ibs equals the sector size of your source block device, then this will keep your output stream in sync with the input in case of read errors. But with wrong
ibs it's very probable a read error will make streams get out of sync, like in this excellent answer. It seems
sync may make your output bigger than input, even when there are no read errors; this will happen if the last block hits EOF before
ibs buffer gets full.
sync are required by POSIX,
fullblock is not.
can I run
dd at the location where the copy failed with a smaller block size to try to get a little bit more data out of it?
In theory -- yes. But this requires you to manually work with
seek=, while still taking care of problems mentioned above. Don't forget you need to recalculate
seek to correspond to the new block size. It's possible, but you will soon wish to automate the process.
And now compare all these issues with GNU
ddrescue default behavior:
- It skips read errors; it gets back to "suspicious" fragments later, trying to read them in smaller and smaller chunks.
- It keeps proper offsets no matter what.