Rsync (简体中文)

From ArchWiki
Jump to: navigation, search
翻译状态: 本文是英文页面 Rsync翻译,最后翻译时间:2016-10-17,点击这里可以查看翻译后英文页面的改动。

rsync 是一个开源工具,可以进行快速的增量的文件传输。

安装

安装 rsync 包。

Note: 必须在源计算机和目标计算机上都安装 rsync

使用方法

搜索 Community ContributionsGeneral Programming 可以得到更多的例子。

作为 cp 的替代

rsync 可以作为 cp 命令的高级替代品,特别在复制较大的文件的场景中:

$ rsync -P source destination

其中 -P--partial --progress 选项的作用是相同的,该选项使得文件可以分块传输并显示传输过程中的进度。

您可能需要使用 -r --recursive 选项使目录被递归地传输。

通过 cp 命令,可以本地复制文件,但 rsync 令人激动的一个特性是可以远程复制文件,例如,在两个不同的主机之间。远程位置可以用主机加冒号进行指定:

$ rsync source host:destination

或者

$ rsync host:source destination

网络文件传输默认使用SSH协议。

无论是本地或远程文件传输, rsync 首先创建每个源文件块校验的索引。此索引用于查找可能存在于目标中的任何相同数据块。一旦这种块存在,块就被就地使用,而不是从源复制。这大大加快了存在小差异的大文件的同步。欲了解更多信息,请参见 official documentation, how rsync works

注意尾随下划

Arch 默认使用 GNU cp (part of GNU coreutils). 然而,rsync 遵循 BSD cp 的约定, 源目录后面带有一个斜杠“/”有着特定的处理。比如:

$ rsync -r source destination

创建一个有着 "source"内容的 "destination/source"目录,命令:

$ rsync -r source/ destination

把"source/"目录下的所有文件全部复制到"destination"目录下,而没有中间的子目录 - 就像你调用了:

$ rsync -r source/. destination

这与 GNU cp 的行为是不同的,在GNU cp中"source" 与 "source/" 意义相同 (不是"source/.")。此外,一些shell可以在你键入Tab补全的时候自动自动给目录追加尾部下划线。由于这些因素,可以有新的或不熟练的rsync用户倾向于忘记的rsync的不同行为,在命令行上留下了结尾的下划线,从而无意间创造一个烂摊子,甚至覆盖重要文件。

谨慎起见,可以使用包装脚在调用rsync之前自动删除尾部斜杠:

#!/bin/zsh
new_args=();
for i in "$@"; do
    case $i in /) i=/;; */) i=${i%/};; esac
    new_args+=$i;
done
exec rsync "${(@)new_args}"

该脚本可以放在某个路径下,并在shell的init文件中把别名改为rsync。

作为备份工具

rsync协议可以很容易地用于备份,只传输自上次备份以来已更改的文件。本节将介绍一个非常简单的基于rsync的计划备份脚本,通常用于复制到可移动介质。对于更详尽的例子, 保留一些系统文件所需的附加选项, 参见 Full system backup with rsync.

自动备份

以下面的脚本为例,该脚本放置于 /etc/cron.daily 目录下,如果 cron daemon 被正确安装和配置,它将每天运行。配置和使用 cron 是本文的范围之外。

首先,创建一个包含相应命令选项的脚本:

/etc/cron.daily/backup
#!/bin/bash
rsync -a --delete /folder/to/backup /location/of/backup &> /dev/null
-a 
表示文件应被存档,这意味着他们的大部分特性被保留 (包括ACLs, 硬链接或扩展属性,如capabilities)
--delete 
指同步源文件的删除操作。

在这里,/folder/to/backup 应该改成需要被备份的路径 (比如 /home),/location/to/backup 是备份应存放的位置 (比如 /media/disk).

最后,脚本必须是可执行的:

# chmod +x /etc/cron.daily/backup

自动用 SSH 备份

如果是通过 SSH 备份到远程主机,改为使用此脚本:

/etc/cron.daily/backup
#!/bin/bash
rsync -a --delete -e ssh /folder/to/backup remoteuser@remotehost:/location/of/backup &> /dev/null
-e ssh 
告诉rsync的使用SSH
remoteuser :远程主机 remotehost 上的用户名
-a 
组中的所有这些选项 -rlptgoD (recursive, links, perms, times, group, owner, devices)

自动使用NetworkManager备份

该脚本在你接入网络后开始备份。

首先,创建一个包含相应命令选项的脚本:

/etc/NetworkManager/dispatcher.d/backup
#!/bin/bash

if [ x"$2" = "xup" ] ; then
        rsync --force --ignore-errors -a --delete --bwlimit=2000 --files-from=files.rsync /folder/to/backup /location/to/backup
fi
-a 
组中的所有选项 -rlptgoD recursive, links, perms, times, group, owner, devices
--files-from 
read the relative path of /folder/to/backup from this file
--bwlimit 
限I / O带宽;每秒千字节


Also, the script must have write permission for owner (root, of course) only (see NetworkManager dispatcher for details).

使用systemd和inotify自动备份

Note:
  • Due to the limitations of inotify and systemd (see this question and answer), recursive filesystem monitoring is not possible. Although you can watch a directory and its contents, it will not recurse into subdirectories and watch the contents of them; you must explicitly specify every directory to watch, even if that directory is a child of an already watched directory.
  • This setup is based on a systemd/User instance.

Instead of running time interval backups with time based schedules, such as those implemented in cron, it is possible to run a backup every time one of the files you are backing up changes. systemd.path units use inotify to monitor the filesystem, and can be used in conjunction with systemd.service files to start any process (in this case your rsync backup) based on a filesystem event.

First, create the systemd.path file that will monitor the files you are backing up:

~/.config/systemd/user/backup.path
[Unit]
Description=Checks if paths that are currently being backed up have changed

[Path]
PathChanged=%h/documents
PathChanged=%h/music

[Install]
WantedBy=default.target

Then create a systemd.service file that will be activated when it detects a change. By default a service file of the same name as the path unit (in this case backup.path) will be activated, except with the .service extension instead of .path (in this case backup.service).

Note: If you need to run multiple rsync commands, use Type=oneshot. This allows you to specify multiple ExecStart= parameters, one for each rsync command, that will be executed. Alternatively, you can simply write a script to perform all of your backups, just like cron scripts.
~/.config/systemd/user/backup.service
[Unit]
Description=Backs up files

[Service]
ExecStart=/usr/bin/rsync %h/./documents %h/./music -CERrltm --delete ubuntu:

Now all you have to do is start/enable backup.path like a normal systemd service and it will start monitoring file changes and automatically starting backup.service.

一个星期差异备份

This is a useful option of rsync, creating a full backup and a differential backup for each day of a week.

首先,创建一个包含相应命令选项的脚本:

/etc/cron.daily/backup
#!/bin/bash

DAY=$(date +%A)

if [ -e /location/to/backup/incr/$DAY ] ; then
  rm -fr /location/to/backup/incr/$DAY
fi

rsync -a --delete --inplace --backup --backup-dir=/location/to/backup/incr/$DAY /folder/to/backup/ /location/to/backup/full/ &> /dev/null
--inplace 
implies --partial update destination files in-place

快照备份

The same idea can be used to maintain a tree of snapshots of your files. In other words, a directory with date-ordered copies of the files. The copies are made using hardlinks, which means that only files that did change will occupy space. Generally speaking, this is the idea behind Apple's TimeMachine.

This basic script is easy to implement and creates quick incremental snapshots using the --link-dest option to hardlink unchanged files:

/usr/local/bin/snapbackup.sh
#!/bin/bash

# Basic snapshot-style rsync backup script 

# Config
OPT="-aPh"
LINK="--link-dest=/snapshots/username/last/" 
SRC="/home/username/files/"
SNAP="/snapshots/username/"
LAST="/snapshots/username/last"
date=`date "+%Y-%b-%d:_%T"`

# Run rsync to create snapshot
rsync $OPT $LINK $SRC ${SNAP}$date

# Remove symlink to previous snapshot
rm -f $LAST

# Create new symlink to latest snapshot for the next backup to hardlink
ln -s ${SNAP}$date $LAST 

There must be a symlink to a full backup already in existence as a target for --link-dest. If the most recent snapshot is deleted, the symlink will need to be recreated to point to the most recent snapshot. If --link-dest does not find a working symlink, rsync will proceed to copy all source files instead of only the changes.

A more sophisticated version checks to see if a certain number of changes have been made before making the backup and utilizes cp -al to hardlink unchanged files:

/usr/local/bin/rsnapshot.sh
#!/bin/bash

## my own rsync-based snapshot-style backup procedure
## (cc) marcio rps AT gmail.com

# config vars

SRC="/home/username/files/" #dont forget trailing slash!
SNAP="/snapshots/username"
OPTS="-rltgoi --delay-updates --delete --chmod=a-w"
MINCHANGES=20

# run this process with real low priority

ionice -c 3 -p $$
renice +12  -p $$

# sync

rsync $OPTS $SRC $SNAP/latest >> $SNAP/rsync.log

# check if enough has changed and if so
# make a hardlinked copy named as the date

COUNT=$( wc -l $SNAP/rsync.log|cut -d" " -f1 )
if [ $COUNT -gt $MINCHANGES ] ; then
        DATETAG=$(date +%Y-%m-%d)
        if [ ! -e $SNAP/$DATETAG ] ; then
                cp -al $SNAP/latest $SNAP/$DATETAG
                chmod u+w $SNAP/$DATETAG
                mv $SNAP/rsync.log $SNAP/$DATETAG
               chmod u-w $SNAP/$DATETAG
         fi
fi

To make things really, really simple this script can be run from a systemd/Timers unit.

图形前端

安装 the grsync package.