The bottom line, try to use rsync all the time. The details follow.
Use scp if you want to strictly populate the destination.
Use rsync if you want to have the choice between strictly populating the destination or populating-and-deleting-at the destination. When you deploy a system the --delete option ensures a clean deployment.
Suppose there is a folder a/empty and no such file as a/empty/file
Suppose there is a folder b/empty and also a file as b/empty/file, in other words, contrary to the appearance, it is not empty.
Contrast the following:
scp -r a/* b
rsync --delete --recursive a/* b.
In the case of rsync, the folder of the same name will be emptied. Of course, for both commands, whatever is caught by the wildcard, *, will cloned anew at the destination.
In order to minimize human error caused by lack of familiarity, just use rsync all the time, omitting the --delete option when you want behaviour like that of scp. rsync looks complicated, so use a script to constrain functionality, hopefully severely.
Here's one.
#!/bin/bash
# Presently, this script is named deploy.sh.
#
# It uses rsync, secured, to do something like a push scp.
# Unlike scp files will be deleted at the destination.
#
# RECOMMENDATION: To minimize risk, always use this script instead of
# invoking rsync directly for push operations.
# Pulling via rsync seems less risky so I do not have a rsync wrapper for pulling.
SCRIPTNAME=$(basename $0)
if [ $SCRIPTNAME != "deploy.sh" ]
then
printf "Are you sure this script is well named?\n"
exit 0
fi
usage() {
printf "usage:\n"
printf "deploy.sh sourceFolder /path/destinationFolder [recursive]\n"
printf "The destination path must be absolute.\n"
printf "The sourceFolder must have the same name as the destinationFolder.\n"
printf "You need to define an EV like this DESTINATIONIP=255.255.255.255.\n"
}
syncMethod1() {
rsync --delete $3 --compress --progress \
--times --perms --owner --group \
--rsh="ssh" \
"$1"/ root@$DESTINATIONIP:"$2"
# note the trailing slash on the source
# note to use --delete you must omit the * at the end of the source
}
syncMethod0() {
BASENAMESOURCE=$(basename $1)
BASENAMEDESTINATION=$(basename $2)
if [ $BASENAMESOURCE = $BASENAMEDESTINATION ]
then
syncMethod1 $1 $2 $3
else
usage
printf "\nThe two folders must have the same name.\n"
fi
}
FIRST=$1
SECOND=$2
THIRD=$3
if [ ! -d "$FIRST" ]
then
usage
printf "\nThe source must be a folder.\n"
elif [ $# != 2 ] && [ $# != 3 ]
then
usage
printf "\nWrong number of arguments.\n"
elif [ -z $DESTINATIONIP ]
then
usage
printf "\nUndefined DESTINATIONIP.\n"
elif [ ${SECOND:0:1} != "/" ]
then
usage
printf "\nDestination path error.\n"
else
if [ $# = 2 ]
then
RECURSIONOPTION="--dirs" # shallow
syncMethod0 $FIRST $SECOND $RECURSIONOPTION
elif [ $# = 3 ]
then
if [ "$THIRD" = "recursive" ]
then
RECURSIONOPTION="--recursive"
syncMethod0 $FIRST $SECOND $RECURSIONOPTION
else
usage
printf "\nUnknown parameter.\n"
fi
fi
fi
exit 0
-u. – Gilles May 31 '12 at 22:46cpandrmwould be considered "harmful" -- and if you define "harmful" as "can screw me over if I do something stupid",rsyncisn't any less harmful. – Shadur Jun 1 '12 at 9:31scp -awill not work, and will be slower. I see no reason to use it, if you have something else at hand. rsync is less harmfull in the sense that it can at least preserve symlinks, so can cp. – mikebloch Jun 10 '12 at 12:09