rsync: Remote Synchronization

rsync is a complete and powerful open source utility that provides fast incremental files transfer.
It efficiently transfers and synchronizes files/directories between storage drive(s) and across networked hosts.

It was created in 1996 by Andrew Tridgell and Paul Mackerras.
It is currently maintained by Wayne Davison.

rsync is freely available under the GNU General Public License.
rsync source code is here

The rsync algorithm is a type of delta encoding, and is used for minimizing network usage.
It efficiently computes/identify which parts (splitted blocks by fragmentation) of a source file match some part of an existing destination file (those parts don’t need to be sent across the communication link), thus minimizing the amount of data to transfer by only moving the portions of files that have changed.

For further speed improvements, the data sent to the receiver can be compressed using any of the supported algorithms.

ssh is the default remote shell for rsync since version 2.6.0 (January 1st 2004)

Install rsync (Debian)
# apt install rsync

rsync version
$ rsync -V

Usage

Local SRC > Local DST
rsync [OPTIONS] SRC [DST]

Push (Local SRC > Remote DST) rsync [OPTIONS] SRC [USER@]HOST:DST
Pull (Local DST < Remote SRC) rsync [OPTIONS] [USER@]HOST:SRC [DST]

Usages with just one SRC arg and no DST arg will list the source files instead of copying:
<type><perms_rwx> <size_bytes> <mtime YYYY/MM/DD> <mtime hh:mm:ss> <relative_path>

IMPORTANT: rsync must be installed on both the source and destination machines

If you still has this error:
rsync: command not found
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream ...


It means Local rsync cannot find the remote rsync executable.
In this case you need to know the path of the remote host’s rsync binary and make it part of the command with --rsync-path=/path/to/remote/rsync

$ which rsync
/usr/bin/rsync  (Debian)

Options

If --delete option is specified, rsync will identify the files NOT present on the sender and delete them on the receiver. This option can be dangerous if used incorrectly! It is recommended to do a simulation run before, using the --dry-run option (-n) to find out which files are going to be deleted.

Each file from the list generated by rsync will be checked to see if it can be skipped.
In the most common mode of operation, files are not skipped if the modification time or size differs.

rsync performs a slower but comprehensive check if invoked with --checksum option.
This forces a full checksum comparison on every file present on both systems.

--checksum, -c
Skip files based on checksum, not mtime AND size.
This changes the way rsync checks if the files have been changed and are in need of a transfer.
Without this option, rsync uses a “quick check” that (by default) checks if each file’ size and time of last modification match between the sender and receiver.
This option changes this to compare a 128-bit checksum for each file that has a matching size.
Generating the checksums means that both sides will expend a lot of disk I/O reading all the data in the files in the transfer, so this can slow things down significantly (and this is prior to any reading that will be done to transfer changed files)

--human-readable, -h
Output numbers in a more human-readable format.
Unit letters: K (Kilo), M (Mega), G (Giga), T (Tera), or P (Peta).

--dry-run, -n
Simulation run (no changes made)

--verbose, -v
Increases the amount of information you are given during the transfer.
By default, rsync works silently.
A single -v will give you information about what files are being transferred and a brief summary at the end.
Two -v options will give you information on what files are being skipped and slightly more information at the end.
More than two -v options should only be used if you are debugging rsync.

--quiet, -q
Decreases the amount of information you are given during the transfer, notably suppressing information messages from the remote server. This option is useful when invoking rsync from cron.

--info=FLAGS
Choose the information output
An individual flag name may be followed by a level number, with 0 meaning to silence that output, 1 being the default output level, and higher numbers increasing the output of that flag (for those that support higher levels).
$ rsync --info=help
$ rsync -av --info=progress2 SRC/ DST/

--progress
Print information showing the progress of the transfer.
This is the same as specifying '--info=flist2,name,progress' but any user-supplied settings for those info flags takes precedence (e.g. --info=flist0 --progress).

While rsync is transferring a regular file, it updates a progress line that looks like this:
<reconstructed_bytes> <%_current_file> <throughput/sec> <remaining_time>

When the file transfer is done, rsync replaces the progress line with a summary line that looks like this:
<filesize_bytes> 100% <throughput/sec> <elapsed_time> (xfr#?, to-chk=???/N)
where ? is the nth transfer, ??? is the remaining files for the receiver to check (to see if they are uptodate or not)

In an incremental recursion scan (--recursive), rsync doesn’t know the total number of files in the files list until it reaches the end of the scan. Since it starts transfering files during the scan, it displays a line with the text “ir-chk” (for incremental recursion check) instead of “to-chk” until it knows the full size of the list, at which point it switches to “to-chk”. “ir-chk” lets you know that the number of files in the files list is still going to increase.

--archive, -a
It is equivalent to -rlptgoD
This is a quick way of saying you want recursion and want to preserve almost everything.
Be aware that it does not include preserving ACLs (-A), xattrs (-X), atimes (-U), crtimes (-N), nor the finding and preserving of hardlinks (-H).
The only exception to the above equivalence is when --files-from is specified, in which case -r is not implied.

--recursive, -r
This tells rsync to copy directories recursively. See also --dirs (-d).
Beginning with rsync 3.0.0, the recursive algorithm used is now an incremental scan that uses much less memory than before and begins the transfer after the scanning of the first few directories have been completed.
It is only possible when both ends of the transfer are at least version 3.0.0.

Some options require rsync to know the full files list, these options disable the incremental recursion mode.
These include: --delete-before, --delete-after, --prune-empty-dirs, and --delay-updates
.

Because of this, the default delete mode when you specify --delete is now --delete-during when both ends of the connection are at least 3.0.0 (use --del or --delete-during to request this improved deletion mode explicitly).
See also the –delete-delay option that is a better choice than using –delete-after.

Incremental recursion can be disabled using the --no-inc-recursive option or its shorter --no-i-r alias.

--delete-during, --del
Request that the file deletions on the receiving side be done incrementally as the transfer happens.
The per-directory delete scan is done right before each directory is checked for updates, so it behaves like a more efficient --delete-before. This option was first added in rsync version 2.6.4. See --delete (which is implied) for more details on file deletion.

--delete-before
Request that the file deletions on the receiving side be done before the transfer starts.
It does imply a delay before the start of the transfer, and this delay might cause the transfer to timeout (if --timeout was specified). It also forces rsync to use the old, non-incremental recursion algorithm that requires rsync to scan all the files in the transfer into memory at once (see --recursive).

--delete-after
Request that the file deletions on the receiving side be done after the transfer has completed.
Important: this option forces rsync to use the old, non-incremental recursion algorithm that requires rsync to scan all the files in the transfer into memory at once (see --recursive). Use --delete-delay instead.

--delete-delay
Request that the file deletions on the receiving side be computed during the transfer (like –delete-during), but removed after the transfer completes. This is more efficient than using --delete-after.
If the number of removed files overflows an internal buffer, a temporary file will be created on the receiving side to hold the names. If the creation of the temporary file fails, rsync will try to fall back to using --delete-after (which it cannot do if --recursive is doing an incremental scan).

--links, -l
By default, symbolic links are not transferred at all.
A message "skipping non-regular" file is emitted for any symlinks that exist.
If --links is specified, then symlinks are recreated with the same target on the destination.
Note that --archive implies --links.

--perms, -p
Preserve permissions
This option causes the receiving rsync to set the destination permissions to be the same as the source permissions.
(See also the --chmod option for a way to modify what rsync considers to be the source permissions)

When this option is off, permissions are set as follows:

– Existing files (including updated files) retain their existing permissions, though the --executability option might change just the execute permission for the file.

– New files get their "normal" permission bits set to the source file’s permissions masked with the receiving directory’s default permissions (either the receiving umask, or the permissions specified via the destination directory’s default ACL), AND their special permission bits disabled except in the case where a new directory inherits a setgid bit from its parent directory.

Thus, when --perms and --executability are both disabled, rsync’s behavior is the same as that of other file copy utilities, such as cp(1) and tar(1).

In summary:
To give destination files (both existing and new) the source permissions, use --perms.
To give new files the destination default permissions (while leaving existing files unchanged), make sure that the --perms option is off and use --chmod=ugo=rwX (which ensures that all non-masked bits get enabled).

The preservation of the destination’s setgid bit on newly-created directories when –perms is off was added in rsync 2.6.7.

--times, -t
Preserve modification times
This tells rsync to transfer modification times along with the files and update them on the remote system.
Note that if this option is not used, the optimization that excludes files that have not been modified cannot be effective.
In other words, a missing -t or -a will cause the transfer to behave as if it used --ignore-times, causing all files to be updated (though rsync’s delta-transfer algorithm will make the update fairly efficient if the files haven’t actually changed, you’re much better off using -t).

--ignore-times, -I
Normally rsync will skip any files that are already the same size and have the same modification timestamp.
This option turns off this "quick check" behavior, causing all files to be updated.

--atimes, -U
Preserve access times
This tells rsync to set the access (use) times of the destination files to the same value as the source files.
nanoseconds are not preserved (set to .000000000), command cp -a does.

IMPORTANT:
There is no option to preserve ctime "status time"

(the timestamp used to record when the inode changed, it is specific to a filesystem)
An inode changes if any of its attributes are updated:
– at creation time (new file)
– file name
– mode/permissions
– owner/group
– hard link count
etc.

The creation of a file is one of the conditions listed above (creation of inode/file).
ctime cannot be preserved when files are brought into a new filesystem.

--open-noatime
Avoid changing the atime on opened file
This tells rsync to open files with the O_NOATIME flag (on systems that support it) to avoid changing the access time of the files that are being transferred. If your OS does not support the O_NOATIME flag then rsync will silently ignore this option. Note also that some filesystems are mounted to avoid updating the atime on read access even without the O_NOATIME flag being set.

--crtimes, -N
MAY NOT BE SUPPORTED, DEPENDS ON THE FILESYSTEM.
This tells rsync to set the create times (newness) of the destination files to the same value as the source files.

--group, -g
Preserve group
This option causes rsync to set the group of the destination file to be the same as the source file.
If the receiving program is not running as the super-user (or if --no-super was specified), only groups that the invoking user on the receiving side is a member of will be preserved. Without this option, the group is set to the default group of the invoking user on the receiving side.

--owner, -o
This option causes rsync to set the owner of the destination file to be the same as the source file, but only if the receiving rsync is being run as the super-user (see also the --super and --fake-super options).
Without this option, the owner of new and/or transferred files are set to the invoking user on the receiving side.

--acls, -A
This option causes rsync to update the destination ACLs to be the same as the source ACLs.
The option also implies --perms.
The source and destination systems must have compatible ACL entries for this option to work properly.
See the --fake-super option for a way to backup and restore ACLs that are not compatible.

--xattrs, -X
This option causes rsync to update the destination extended attributes to be the same as the source ones.

--hard-links, -H
This tells rsync to look for hard-linked files in the source and link together the corresponding files on the destination. Without this option, hard-linked files in the source are treated as though they were separate files.

This option does NOT necessarily ensure that the pattern of hard links on the destination exactly matches that on the source.

Usual Usage

Local SRC_DIR > Local DST_DIR
NOTE: By default, if Local DST_DIR does not exist it is created

Copy SRC_DIR inside /path/to/local/DST_DIR/ : /path/to/local/DST_DIR/SRC_DIR
$ rsync -av --info=progress2 /path/to/local/SRC_DIR /path/to/local/DST_DIR

Copy <src_path>'s content inside <dst_path>/
$ rsync -av --info=progress2 <src_path>/ <dst_path>/
$ rsync -av --info=progress2 <src_path>/* <dst_path>/

Local SRC_FILE > Local DST

$ rsync -av --info=progress2 /path/to/local/SRC_FILE /path/to/local/DST

IF DST is a directory, it copies SRC_FILE inside DST (DIR)

IF DST is a file, its content is replaced with the content of SRC_FILE
(with -a option ONLY mtime is the same, atime, ctime are different, you may use -U + -N options)

If DST does not exist :
– if there is a trailing slash ‘/’ it creates the directory DST (only for a direct subdirectory of an existing path “mkdir -p does not work” ) AND copies SRC_FILE inside DST

– otherwise it creates file DST (copy of SRC_FILE)