Wandering Thoughts archives


The hidden danger of using rsync to copy files instead of cp

I have a long standing reflexive habit that most of them time when I want to copy files around, I reach for 'rsync -a' by default. I do it on the command line, and I do it in things like our local postinstall system setup scripts. It's not really necessary these days ('cp -a' now works fine on everything I commonly use), but I started doing this in an era when rsync was the clearly safest choice for a 'copy file, preserving all attributes, no matter what system I'm on' command. Today I made a mistake and was reminded that this is not necessarily the best idea, because there is a small difference in behavior between rsync and cp here.

What happened today is that in a system setup script, I wrote:

set -e
rsync -a /master/loc/etc/cron.d/cron-thing /etc/crond.d/

I ran the script, it went fine, and then afterward the system didn't actually seem to be doing what the cron.d entry was supposed to have it do. I spent some time wondering if I'd gotten some other bit of the system setup wrong, so that the script I was invoking from cron couldn't do anything, and then finally I looked in /etc/cron.d for some reason and the penny dropped.

You see, the important difference between rsync and cp here is that rsync will create a destination directory if necessary and cp won't. The drawback of this sometimes-handy behavior is that rsync's behavior hides typos. Had I written 'cp -a ... /etc/crond.d/', the cp would have errored out (and then the entire script would have aborted). With rsync, it quietly created /etc/crond.d and put my cron-thing in it, just as I'd typed but not as I'd wanted.

After this happened, I went back through this script and turned all of my reflexive 'rsync -a' usage into 'cp -a'. I've been burned once, I don't need to stub my toe a second time. I don't currently plan to revise our existing (working) scripts just for this, but certainly I'm now going to try to shift my reflexes and use 'cp -a' in the future.

(In this sort of context, even if I want the directory created too I think it's better to use 'mkdir -p' in order to be explicit about it. On the command line I might exploit rsync's side effect, but in a script there's no reason to be that compact and obscure.)

RsyncForCopiesDanger written at 23:14:50; Add Comment

By day for July 2018: 3 4 6 8 28 30 31; before July; after July.

Page tools: See As Normal.
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.