The problem: One out of 14,000+ files is unreadable and hard locks the entire disk system in Mac OS X if accessed. I need to copy everything in the directory hierarchy except that single problem file. cp -r, Drag and drop in the finder, ditto, rsync, etc... all eventually try to copy the file and lock the system.
This problem cropped up after a customer returned from a trip with a severely damaged PowerBook G4. He had the machine in his bag, hanging on a hook, which wasn't secured to the wall very well. The hook ripped out of the wall, the powerbook caught the edge of a metal trash can... Game over.
The upshot is that his new MacBook Pro was already waiting for him when he returned home, so now it's just a matter of copying his data from the damaged PowerBook to the new MacBook Pro. I removed the 2.5" drive and attached it to my handy ATA-USB adapter.
Unfortunately, shortly after starting the copy with the Finder, the progress bar would freeze, the disk activity light would freeze, and my workstation became completely locked. I could still interact with the machine, but even shutdown -r now and reboot failed to actually restart the machine. I had to resort to power cycling, which I never like.
Fed up with the finder, I decided to try rsync. After starting the copy with the command:
rsync -avxHE --progress /Volumes/Users/herb /Scratch/Herb/Users/
Which quickly (3.7% actually) arrived at the problem file. The progress stopped, and I could see that no more disk access was taking place. Luckily, rsync was apparently waiting patiently for a read() that'd never finish, and it didn't lock my system like the finder did. I decided to just flip the power switch on my ATA-USB bridge since I knew I wasn't doing any writes to the disk. The system handled the disappearing disk fine, cleaned up the mounted volumes, and rsync gracefully reported that the rest of it's file listing had now vanished. I was able to quit rsync by sending a break.
With rsync, I was able to get the file name of the exact file that was tripping up the recursive copy. I added the full path to the file to a text file named files_to_exclude.txt then re-started rsync:
rsync -avxHE --progress --exclude-from /tmp/files_to_exclude.txt /Volumes/Users/herb /Scratch/Herb/Users/
This time, rsync skipped the problem file and finished the other 96% of work it had to do without a problem.
So, if you're in a situation where recursive file copies are failing on a single file, rsync might come in handy, allowing you to skip over specific files and copy the rest.