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/cron
d
.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.)