Rsync
rsync 是一个常用的 Linux 应用程序,用于文件同步。它可以在本地计算机与远程计算机之间,或者两个本地目录之间同步文件。
rsync 在 Linux 安装,安装命令如下:
# ubuntu
sudo apt install rsync
# centos
sudo yum install rsync
如果使用 Windows ,可以使用 cwRsync,它是 Windows 客户端 GUI 的一个包含 Rsync 的包装。您可以使用 cwRsync 快速远程文件备份和同步。
基本用法
在本机使用 rsync 命令时,可以作为 cp 和 mv 命令的替代方法,将源目录同步到目标目录。
rsync -r source destination
其中,-r 表示递归,即包含子目录。source 目录为源目录,destination 表示目标目录。
如果有多个目录需要同步,可以写成下面这样。
rsync -r source1 source2 destination
我们可以使用-a 参数替代-r,除了可以递归同步以外,还可以同步元信息(比如修改时间,权限)。由于 rsync 默认使用文件大小和修改时间决定文件是否需要更新,所以-a 比-r 更有用。下面的用法才是常见的写法。
rsync -a source destination
目标目录 destination 如果不存在,rsync 会自动创建。执行上面的命令后,源目录 source 被完整地复制到目标目录 destination 下面,即形成了 destination/source 的目录结构。
如果只想同步源目录 source 下的内容到目标目录 destination,则需要在源目录后面加上斜杠。
rsync -a source/ destination
如果不确定 rsync 执行后会产生什么结果,我们可以用-n 或 --dry-run 模拟执行结果。
rsync -anv source/ destination
-n 参数模拟命令执行结果,不真实执行命令。-v 参数将结果打印到终端。
默认情况下,rsync 只确保源目录的所有内容都复制到目标目录。它不会使两个目录保持相同,并且不会删除文件。如果要使用目标目录成为源目录的镜像副本,使用--delete 参数,这将删除只存在于目标目录,不在源目录的文件。
rsync -av --delete source/ destination
如果我们想排除某些文件或目录,可以使用--exclude 参数指定排除模式。
rsync -av --exclude '*.txt' source/ destination
该命令将排除所有后缀为 txt 的文件。
如果要排除隐藏文件,可以这样写--exclude ".*"
,如果要排除某个目录里面的所有文件,但不排除目录本身,可以这样写--exclude 'dir1/*'
,多个排除目录,可以用多个--exclude 参数。也可以简写为--exclude={'file1.txt','dir1/*'},这个需要在 Linux 环境下。
如果排除模式很多,我们可以将其写入一个文件,每个模式一行,然后使用参数--exclude-from 指定这个文件。
rsync -av --exclude-from='exclude-file.txt' source/ destination
如果只想同步某类型文件,可以使用下面的语法:
rsync -av --include="*.txt" --exclude="*" source/ destination
rsync 除了支持本地两个目录之间的同步,也支持远程同步。它可以将本地内容,同步到远程服务器。
rsync -av source/ username@remotehost:destination
如何 ssh 端口不为默认的 22,则使用下面的命令:
rsync -avP -e 'ssh -p 2222' --exclude="*.log" ./test username@remotehost:destination
rsync 默认使用 SSH 进行远程登录和数据传输。如果想使用 rsync 协议,需要在同步的目标服务器安装和运行 rsync 守护程序,则可以使用 rsync://协议(默认端口 873)进行传输。
rsync -av source/ 192.168.0.1::module/destination
或
rsync -av source/ rsync://192.168.0.1/module/destination
module 不是实际路径名,是 rsync 守护程序指定的一个资源名,由管理员分配。想查看 rsync 守护程序分配的 module 列表,使用下面的命令:
rsync rsync://192.168.0.1
到重点了,rsync 的最大特点是它可以增量备份,即只复制有变动的文件。它也支持使用基准目录,即将源目录于基准目录之间变动的部分,同步到目标目录。
具体做法是,第一次同步是全量备份,所有文件在基准目录里面同步一份。以后每一次同步都是增量备份,只同步源目录与基准目录之间有变动的部分,将这部分保存在一个新的目标目录。这个新的目标目录中,只有那些变动过的文件。
rsync -a --delete --link-dest /compare/path /source/path /target/path
上面命令中,--link-dest 参数指定基准目录/compare/path,然后源目录/source/path 跟基准目录进行比较,找出变动的文件,将它们拷贝到目标目录/target/path。那些没有变动的文件则会生成硬链接。这个命令的第一次备份是全量备份,后面就是增量备份了。
下面是一个脚本示例,备份用户主目录。
#!/bin/bash
# A script to perform incremental backups using rsync
set -o errexit
set -o nounset
set -o pipefail
readonly SOURCE_DIR="${HOME}"
readonly BACKUP_DIR="/mnt/data/backups"
readonly DATETIME="$(date '+%Y-%m-%d_%H:%M:%S')"
readonly BACKUP_PATH="${BACKUP_DIR}/${DATETIME}"
readonly LATEST_LINK="${BACKUP_DIR}/latest"
mkdir -p "${BACKUP_DIR}"
rsync -av --delete \
"${SOURCE_DIR}/" \
--link-dest "${LATEST_LINK}" \
--exclude=".cache" \
"${BACKUP_PATH}"
rm -rf "${LATEST_LINK}"
ln -s "${BACKUP_PATH}" "${LATEST_LINK}"
上面脚本中,每一次同步都会生成一个新目录${BACKUP_DIR}/${DATETIME},并将软链接${BACKUP_DIR}/latest指向这个目录。下一次备份时,就将${BACKUP_DIR}/latest 作为基准目录,生成新的备份目录。最后,再将软链接${BACKUP_DIR}/latest 指向新的备份目录。
注意:在 Windows 上你可以使用 WSL Linux,在 Linux 使用 rsync 要可靠稳定很多。我测试 Windows 的 cwRsync 连接 Linux 服务器报错,网上有帖子说是 SSH 问题。
当在 WSL Linux 使用计划任务 cron 进行定时备份时,你会发现不生效?
可以通过以下方法解决:
usermod -a -G crontab (username)
service cron start
在 WSL Linux 中,如果要 cron 服务开机自启,有点麻烦。请参考 wsl linux 文章。
ws.run "wsl -d Ubuntu -u root /etc/init.d/cron start",vbhide
应用场景
备份你的代码,上传 mdbook 书籍到你的网站。