rsyncThe command: rsync -aE --delete ~/Documents/ /Volumes/Backup/Documents/
-E is the macOS-specific half, and leaving it out silently loses extended attributes and resource forks.
-a is archive mode: recurse, and preserve permissions, ownership, timestamps and symlinks.
It is the flag everybody knows.-E preserves macOS extended attributes and resource forks. Finder tags, quarantine flags,
custom icons and a good deal of application metadata live there. Without it they are gone, and nothing tells
you.--delete removes files from the destination once they are gone from the source. This is what
makes the copy a mirror, and it is the flag to think hardest about.-v for output, -n for a dry run. Always dry-run a command with
--delete in it the first time.~/Documents copies the folder into the destination, giving you
/Volumes/Backup/Documents/Documents. ~/Documents/ copies its
contents, which is almost always what you meant. In a command that also says
--delete, getting it wrong deletes whatever else was in the destination.--exclude for things not worth copying: --exclude '.DS_Store',
--exclude 'node_modules', --exclude 'Library/Caches'.macOS ships a version of rsync that is adequate for this. If you want the newer upstream one,
Homebrew has it, and its ACL handling on macOS is better.
rsync makes the destination look like the source. That is a copy, and a copy is not history.
A document you deleted last Tuesday is gone from the backup the next time it runs. So is the good version of
a file you have since overwritten, and so is everything ransomware got to before the job fired.
Dropping --delete does not fix this. It gives you a destination that accumulates every file you
have ever had, still with exactly one version of each, and no way to tell what is current.
--link-destThe standard trick is to make a new dated directory each run and hard-link unchanged files to the previous one, so identical files cost nothing:
DEST=/Volumes/Backup
TODAY=$(date +%F)
rsync -aE --delete \
--link-dest="$DEST/latest" \
~/Documents "$DEST/$TODAY"
ln -snf "$DEST/$TODAY" "$DEST/latest"
Now each dated folder looks like a full backup and only the changed files occupy space. This is roughly the idea Time Machine is built on.
Two caveats. Hard links mean the copies are not independent: corruption in the underlying block affects every snapshot sharing it. And it needs a filesystem with hard link support, so it works on an external drive and not inside most cloud folders.
rsync does not encrypt anything at rest. If the destination is a cloud folder or a drive that
leaves the building, encrypt before you write:
tar -cJf - ~/Documents | openssl enc -aes-256-cbc -pbkdf2 -out /Volumes/Backup/documents.tar.xz.enc
That is one opaque archive: no incremental copying, no restoring a single file without unpacking the lot, and one passphrase between you and everything. It is a real trade-off, and it is the point at which most people stop hand-rolling.
cron still exists on macOS but launchd is the supported route. A plist in
~/Library/LaunchAgents/ with a StartCalendarInterval runs your script daily. macOS will
ask for Full Disk Access for whatever runs it, because reading Documents and Desktop is protected.
Whatever you schedule, have it write its result somewhere you will actually see, and check that the backup is recent:
find /Volumes/Backup -type f -newermt '-7 days' | head
A silent job is the failure mode. It does not stop with an error on your screen, it stops in the night four months ago.
The commands above cover copying. What they do not cover is what you actually want on the day something goes wrong: versions that survive a mirror run, encryption that still lets you restore one file, a read-back that checks every piece against its hash, and something that tells you when the drive has not been seen for a week.
Each of those is a weekend of scripting, and then it is yours to maintain. Copy Shelter is the same idea with those parts built in, and it is free for one location.
rsync copy lose Finder tags?Because -a alone does not carry extended attributes on macOS. Add -E. If you also need ACLs, use -A, and consider the Homebrew build, which handles them more reliably than the system one.
Yes, either to a mounted share under /Volumes or over SSH to the NAS itself. Over SSH is faster and does not depend on the mount being present, and many NAS boxes have rsync built in.
sudo?Not for your own home folder. You do need to grant Full Disk Access to Terminal, or to whatever launchd runs, before macOS will let it read Documents, Desktop and Downloads.
--delete dangerous?It is doing exactly what you asked, which is the dangerous part. Dry-run with -n the first time, and make sure the destination path is right: a typo with --delete pointed at the wrong directory removes files there.
Yes, that is what rsync is for. Run it again and it transfers only what is missing or changed. Add --partial so a half-transferred large file is kept and resumed.
Next: how to check the copy is actually readable.