The base requirement of the rsync system is that you install the rsync program on the source and destination hosts. The easiest way to transfer files is to use a remote shell account. This section assumes that you want to transfer files to or from a machine to which you have SSH access.
On the surface, the rsync command is not much different than scp or rcp. In fact, you can run rsync with the same arguments as those utilities. For example, to copy a group of files to your home directory on host, you can run this command:
rsync file1 file2 ... host:
However, given your current system and rsync configuration, this command probably will not work, because the rsync program defaults to using rsh as the remote shell, and as you saw in Section 6.7, you shouldn't use something this insecure. To get around this, you can tell rsync to use ssh with the --rsh option:
rsync --rsh=ssh file1 file2 ... host:destination_dir
Look out for this error message:
rsync not found rsync: connection unexpectedly closed (0 bytes read so far) rsync error: error in rsync protocol data stream (code 12) at io.c(165)
This notice says that your remote shell can't find rsync on its system. If rsync isn't in the remote path but is on the system, use --rsync-path=path to manually specify its location.
If you don't want to type --rsh=ssh every time that you invoke an rsync command, set the RSYNC_RSH environment variable to ssh. The remainder of the commands in this chapter assume that you have done this.
If your username is different on the remote host, add user@ to the hostname, where user is your username on host:
rsync file1 file2 ... user@host:destination_dir
With no extra options, rsync copies only files. In fact, if you specify just the options described so far and you supply a directory dir as an argument, you will see this message:
skipping directory dir
To transfer entire directory hierarchies, complete with the same symbolic links, permissions, modes, and devices, use the -a option, as in this example:
rsync -a dir host:destination_dir
If you're not too sure what will happen when you transfer the files, use the -n option to operate rsync without actually copying any files. The -n option implies the -v (verbose mode) option, showing details about the transfer and the files involved:
rsync -na dir host:destination_dir
The output looks like this:
building file list ... done ml/nftrans/nftrans.html [more files] wrote 2183 bytes read 24 bytes 401.27 bytes/sec
By default, rsync copies files and directories without considering the previous contents of the destination directory. For example, if you transferred the directory d containing the files a and b to a machine that already had a file named d/c, the destination would contain d/a, d/b, and d/c after the rsync. To make an exact replica of the source directory, you must delete files in the destination directory that do not exist in the source directory, such as d/c in this example.
Use the --delete option to remove files from the destination that don't reside in the local directory, like this:
rsync -a --delete dir host:destination_dir
Note? |
Again, if you're not certain about your transfer, use the -n option to tell you if rsync wants to delete any files before it actually performs the removal. |
You may also wish to use --max-delete=n to make sure that rsync deletes no more than n files in the target directory. This option essentially amounts to a last-ditch effort not to delete large numbers of files when there's some problem on the source side. However, it will still delete files until reaching n deleted files, and in fact, you may notice that your version of rsync might have a bug, where it deletes one more than n files.
You have to be particularly careful when specifying a directory as the source in an rsync command line. Consider this command:
rsync -a dir host:dest_dir
Once this command completes, you will have a directory dir inside dest_dir on host. However, adding a slash (/) significantly changes the behavior:
rsync -a dir/ host:dest_dir
Here, rsync copies everything inside dir to dest_dir on host without actually copying the dir directory itself. The dir directory will not exist on host after the operation. Therefore, you can think of a transfer of dir/ as an operation similar to cp dir/* dest_dir on the local filesystem.
Let's consider an example. Say that you have a directory d containing the files a and b (d/a and d/b). You run the following command to transfer them to the c directory on host:
rsync -a d/ host:c
After the transfer completes, the directory c contains copies of a and b, but not d. If, however, you had omitted the trailing / on d, c would have gotten a copy of d, with a and b inside, so that as a result of the transfer you'd have files and directories named c/d/a and c/d/b on the remote host.
When transferring files and directories to a remote host, accidentally adding a / after a path would normally be nothing more than a nuisance; you could then go to the remote host, add the dir directory, and put all of the transferred items back in dir. Unfortunately, you must be careful to avoid disaster when combining the trailing / with the --delete option. If you use the --delete option to transfer dir to dest_dir without the slash, rsync ignores everything in dest_dir except dir. Using dir/, on the other hand, makes rsync compare the contents of dir against dest_dir and makes dest_dir look exactly like dir. Therefore, you can accidentally delete a whole bunch of files in dest_dir.
Warning? |
Be wary of your shell's automatic filename completion feature. GNU readline and many other completion libraries tack a trailing slash onto a completed directory name. |
One very important feature of rsync is its ability to exclude files and directories from a transfer operation. Let's say that you would like to transfer a local directory called src to host, but you want to exclude anything named RCS. You can do it like this:
rsync -a --exclude=RCS src host:
It's important to note that this command excludes all files and directories named RCS because --exclude takes a pattern, not an absolute filename. If you want to exclude only one specific item, specify an absolute path that starts with /, as in this example:
rsync -a --exclude=/src/RCS src host:
Note? |
The first / in /src/RCS in this command is not the root directory of your system, but rather, the very base directory of the transfer. |
Here are a few more tips on exclude patterns:
You may have as many --exclude parameters as you like.
If you use the same patterns time and again, place those patterns in a plain-text file (one pattern per line), and then use --exclude-from=file.
To exclude directories named item but include files with this name, use a trailing slash: --exclude=item/.
The exclude pattern is based on a full file or directory name component and may contain simple wildcards. For example, t*s matches this, but does not match ethers.
If you exclude a directory or filename, but find that your pattern is too restrictive, use --include to specifically include another file or directory.