While rsync is different than cp and mv, I dislike the cp and mv destination-state-dependent behaviour.
With rsync, destination paths are defined by the command itself and the command is idempotent. I don't usually need to know what the destination is like to form a proper command (though oopsies happen, so verify before using --delete).
With cp/mv - the result depends on the presence and type of the destination.
E.g. try running cp or mv, canceling then restarting. Do you need to change the arguments? Why?
mkdir s1 s2 d1
touch s1/s1.txt s2/s2.txt
# this seems inconsistent
cp -r s1 d1 # generates d1/s1/s1.txt
cp -r s2 d2 # generates d2/s2.txt
mkdir s1 s2 d1
touch s1/s1.txt s2/s2.txt
# I don't use this form, but it is consitent
rsync -r s1 d1 # generates d1/s1/s1.txt
rsync -r s2 d2 # generates d2/s2/s2.txt
# Same as above but more explicit
rsync -r s1 d1/ # generates d1/s1/s1.txt
rsync -r s2 d2/ # generates d2/s1/s2.txt
# I prefer this form most of the time:
rsync -r s1/ d1/ # generates d1/s1.txt
rsync -r s2/ d2/ # generates d2/s2.txt
I simply try to use trailing slashes wherever permitted and the result is amply clear.
With rsync, destination paths are defined by the command itself and the command is idempotent. I don't usually need to know what the destination is like to form a proper command (though oopsies happen, so verify before using --delete).
With cp/mv - the result depends on the presence and type of the destination. E.g. try running cp or mv, canceling then restarting. Do you need to change the arguments? Why?
I simply try to use trailing slashes wherever permitted and the result is amply clear.