Zombie Zen

Today I Learned: rsync

By Ross Light

rsync is a wonderfully useful utility for copying files both locally and between machines. It makes a reasonable effort to copy only files that have changed, which can save a tremendous amount of time in many scenarios. However, I’ve always been a bit daunted by its plethora of command-line options, and would always resort to its man page for every invocation. Thus, it would never stick in my set of tools I would commonly use. After doing some work where rsync really was the only tool for the job, I decided to finally make a little cheatsheet on how to use rsync.

The syntax for an rsync command-line is similar to cp:

rsync [options] SOURCE [...] DEST

Unlike in cp, trailing slashes in arguments are significant. A trailing slash on a SOURCE argument will copy the contents of the directory to the destination. When you intend to copy into a directory, it is best to include a trailing slash on the DEST argument to avoid a case of a single source file being copied to the intended directory path.

Remote machine arguments take the same [USER@]HOST:PATH syntax as in scp.

Common Options

Option Shorthand Description
--recursive -r Copy directories. Almost always useful.
--links -l Copy symlinks as symlinks instead of dereferencing
--perms -p Preserve file mode permissions
--owner -o Preserve file owner
--group -g Preserve file group
--devices Preserve device files
--specials Preserve special files
--times -t Preserve modification times
--archive -a Same as --recursive --links --perms --times --group --owner --devices --specials
--compress -z Compress file data during transfer
--progress Show progress during transfer
--partial Keep partially transferred files when the transfer is interrupted instead of deleting them. Future file transfers can reuse such files.
-P Same as --progress --partial
--delete Delete any files from the destination directory that did not appear in the source
--dry-run -n Simulate operation without changing anything. Almost useless without --verbose.
--verbose -v Print operations as they occur
--exclude Exclude a pattern from being copied or deleted
--include Ensure a pattern will be copied or deleted

Options can be negated using --no-OPTION, where OPTION is either a full option name or a shorthand. Thus, a quick way of specifying that you want to preserve everything except file UIDs and GIDs is -a --no-g --no-o.

Filter Rules

The --filter option is a generalization of the --include/--exclude options. Each filter rule starts with a verb like include or exclude and ends with a pattern. For complex or persistent filter rules, you can write a file called .rsync-filter then use the -F option to have that apply. Using the flag twice (i.e. -FF) will prevent the files from being copied to the destination.

Filter Rule Patterns

Patterns for --exclude, --include, and --filter are similar to gitignore patterns:

  • *, **, and ? have their usual shell-globbing meanings.
  • Patterns without slashes match the final filename (i.e. anywhere in the tree).
  • Patterns with a leading slash will be rooted to the top of the tree.
  • A pattern without a leading slash but containing a slash will match anywhere in the tree (i.e. will act as if you prefixed it with /**/). This usually isn’t what you want.


Posted at