Bootstrap

如何在 Linux 中使用 rsync 传输文件

188f950d10e388ac8c2e0c35b1e09be7.gif

作者 | 刘光录

来源 | TIAP

rsync(远程同步,Remote Sync)是一种在系统中或两个系统之间复制文件和目录的同步工具。rsync 的一个最大的优点,就是它只复制更改的文件,因而可以减少 CPU 消耗,在复制文件时节省带宽和时间。

rsync 相比于 scp 的优点

我们大家可能知道 scp(secure copy 的简写),也是一个通过 ssh 在两个远程系统之间复制文件的工具。但是 rsync 更好用,表现在以下三个方面:

1)rsync 只复制更改的文件,而 scp 会复制所有的每个文件,并且会覆盖旧的文件,因此,rsync的速度更快;

2)rsync 也可以在没有加密的情况下工作,这可以减少系统开销(仅用作对加密传输没要求的情况下,有安全风险时慎用);

3)rsync 支持断点续传(但是scp不可以)。

在大多数Linux发行版中,rsync 默认是没有安装的,因此需要手动安装。在 Ubuntu 和 Debian 系统中,可以使用如下命令安装:

sudo apt install rsync

rsync 命令示例

rsync命令的结构如下:

rsync [OPTIONS] Source Destination

上述命令中 Source 为文件的源地址,Destination 为目的地址。源地址和目的地址可以是本地路径也可以是远程路径,格式为:username@hostname:path/to/file

我们接下来看几个实际的例子。

注意:假如我们有一个目录 A,那么 A 和 A/ 是不一样的。A/ 指的是在目录A下的所有文件,但是不包括 A 本身;所以 复制 A 会在目的地址新建一个目录,然后复制 A 中的文件。但是复制 A/ 只会将 A 中的文件复制到目的地址中。

1.  同步本地文件(单向同步)

我们假设要将文件从目录 A 复制到 Backup-A-dir 中:

rsync A/ Backup-A-dir/

上述命令会将 A 中的文件复制到 Backup-A-dir 中。但Backup-A-dir中的文件不会同步到A中,这就是为什么会被称为单向同步的原因。

2. 同步远程文件(单向同步)

远程系统和本地系统之间同步文件,命令是类似的。注意,源地址和目的地址都可以是本地文件系统路径或者远程系统(ssh)路径。

rsync dev/build username@hostname:~/Backup

3. 双向同步

上述命令是将文件从源地址复制到目的地址。我们假设有这样一种情况,就是在目的地址中存在一些额外文件,但是这些额外文件在源地址中并不存在,那么在单向同步的时候,不会将目的地址中的这些额外文件删掉。如果我们想要在同步的时候删掉目的地址中的这些额外文件(也就是需要与源地址中的文件保持绝对一致),那么就需要使用双向同步。

要保持源地址和目的地址中的文件一致,将 --delete 选项添加到命令中即可:

rsync A/ Backup-A-dir/ --delete

4. 复制完成后删掉源文件

如果要在复制完成后,删掉源文件,需要在命令中添加 --remove-source-files 选项:

rsync A/ Backup-A-dir/ --remove-source-files

删掉源文件需要慎重,要确保已经保存好了备份,并且待删数据已经没有用了。

5. “包括”和“排除”文件

如果你需要(或者不需要)传输某些指定的文件,可以使用 --include 或者 --exclude 选项,后面跟上 = 和 指定文件的模式表达式:

rsync A/ Backup-A-dir/ --include=*.py --exclude=*.tmp.py

以上命令会传输所有以 .py 作为后缀名的文件,排除掉所有以 .tmp.py 为后缀名的文件。

上面提到的模式表达式,可以是正则表达式。

注:如果 include 或 exclude 的文件列表比较长,可以将其存储在文件中,使用的时候将文件名称传递给 --include-from 或者 --exclude-from 选项。

6. 通过 ssh 传输

如果想要通过 ssh 传输文件,那么需要使用 -e 选项来指定 ssh:

rsync -e ssh A/ username@hostname:~/Backup-A-dir/

这是传输文件到远程系统的首选方式,因为它传输的时候是加密的。需要注意的是,由于是加密传输,会产生系统开销,所以这比正常传输更耗时。

要使用 ssh 传输,还需要确保服务器端已经配置了ssh。

7. 详情模式

Linux 中的大多数命令都会有详情选项,用于在终端中记录命令的操作。rsync 也不例外。

使用 -v 或者 -verbose 选项来显示详情,它会列出正在执行的操作和进度。这在调试的时候很方便。

rsync A/ Backup-A-dir/ -v -r

其输出类似于如下的输出:

$ rsync A/ Backup-A-dir/ -v -rsending incremental file listcreated directory Backup-A-dir./file1.txtfile2.txtfile3.txtfile4.txtfile5.txtfile6.txtsent 388 bytes received 168 bytes 1,112.00 bytes/sectotal size is 0 speedup is 0.00

8. 只运行(运行但是不执行复制操作)

如果你只是想知道在不进行实际传输的情况下,需要复制的文件,那么可以使用 --dry-run(或者 -n)选项:

除复制部分外,它与正常rsync命令一样执行所有操作。它将列出要复制或删除的文件(如果需要),然后在复制之前停止。

$ rsync -v A/ Backup-A-dir/ –dry-run
sending incremental file list
created directory Backup-A-dir
./
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt
file6.txt
sent 172 bytes received 72 bytes 488.00 bytes/sec
total size is 0 speedup is 0.00 (DRY RUN)

注意,上述命令需要带有参数 -v 来显示详情,否则不会显示任何结果。

9. 显示传输进度

要显示传输进度,可使用 --progress 选项:

rsync A/ Backup-A-dir/ --progress

上面的命令将显示一个类似于下面的进度条:

$ rsync -r A/ Backup-A-dir/ –progresssending incremental file listcreated directory Backup-A-dir./file1.txt 0 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=5/7)file2.txt 0 100% 0.00kB/s 0:00:00 (xfr#2, to-chk=4/7)file3.txt 0 100% 0.00kB/s 0:00:00 (xfr#3, to-chk=3/7)file4.txt 0 100% 0.00kB/s 0:00:00 (xfr#4, to-chk=2/7)file5.txt 0 100% 0.00kB/s 0:00:00 (xfr#5, to-chk=1/7)file6.txt 0 100% 0.00kB/s 0:00:00 (xfr#6, to-chk=0/7)

10. 压缩和传输数据

使用 -z 选项可以压缩要传输的数据,压缩后在传输数据会更加节省网络带宽和时间。它将在目的地自动解压缩。

当传输的数据量很大时,使用 -z 选项进行压缩会节省时间,但是对于小文件,应该避免使用 -z,因为处理压缩的开销会超过正常情况下的时间。

rsync -z A/ Backup-A-dir/

11. 递归复制文件和目录

以上所有命令只复制文件,不复制子目录(每个Linux命令都是这样)。因此,不会复制这些子目录中的文件。要复制子目录中的文件,可以使用 -r 选项。

rsync -r A/ Backup-A-dir/

12. 归档并保留元数据

如果要保留符号链接、时间戳、文件权限、文件的用户和组所有权,可以使用 -a 选项。

rsync -a A/ Backup-A-dir/

结合使用 -r 可以递归复制文件并保留复制文件的元数据。

13. 设置文件大小限制

为了避免传输大文件,可以使用 --max-size 选项设置文件大小限制。

rsync --max-size='100K' A/ Backup-A-dir/

14. 设置带宽限制

--bwlimit 选项可以设置最大传输速率,单位是 kbps。

rsync --bwlimit=100 A/ Backup-A-dir/

15. 断点续传

如果文件传输不完整,可以使用 rsync 命令保留不完整的下载,以便在下一次发出相同命令时继续传输。

要恢复传输,使用 --append 选项:

rsync --append A /Backup-A-dir/

多线程传输

以上都是一些基本的命令,是在单个进程中复制文件。如果文件特别大,比如有5TB,那么整个传输过程的持续时间会非常长。这里介绍一种方法可以加快传输速度,那就是使用 parallel

parallel 是用于执行并发作业的GNU程序,可以和 rsync 结合使用。

与 rsync 一样,parallel 也需要手动安装:

sudo apt install parallel

在我们正式介绍 parallel 之前,先来了解一些它是如何工作的。我们来考虑一个类比:

假设有1000个鸡蛋和100个篮子,然后每个篮子配备一个无人机,任务就是将这1000个鸡蛋交付给客户。经理给每个篮子分配10个鸡蛋,并将篮子交给无人机进行交付。这样每个无人机都会执行一个操作(就是送篮子中的鸡蛋,我们的例子中,就好比是 rsync 处理10个文件)。经理监督无人机的工作。请注意,每个无人机都不知道是否还有其他无人机,只有经理才知道。

类似地,rsync像无人机一样执行文件传输,而 parallel 就担任经理的角色。

parallel 将要传输的文件分割成若干份(每份都是一个文件列表),每份都由rsync启动一个进程进行传输。rsync不知道其他并行的进程,也不具备并行传输的能力。而parallel就启动rsync,来启动并管理多个并行进程。

因此,parallel 命令由两部分组成,一个是参数(鸡蛋/文件),另一个是并行进程命令(管理器)。

ls A/* | parallel -j 20 rsync A/{} /Backup-A-dir/

在上述命令中,管道符号 | 左侧的部分,输出是一个文件列表,每个文件都作为一个参数;在 parallel 命令中,{} 则表示这些参数(相当于占位符)。

-j n,它给- n 一个数字来表示任务数(或者进程数),本例中,n 是20;之后是 rsync 的常用命令,来处理每个参数(管道符号左侧的文件列表)。最后,它会被捆绑到20个进程中,并行执行。

注意,上面的 rsync 命令就是普通的rsync命令,跟我们上面介绍的用法完全一样,就像不用 parallel 时一样,可以添加任何选项(比如 -z, -a, -e ssh等)。

关于 garallel 的详细介绍,可参考:

https://www.gnu.org/software/parallel/

使用 rsync 时的一些常见故障

使用 rsync 时可能会遇到一些问题,下面是一些常见的错误。

1. rsync 权限被拒绝(rsync permission denied)

当你使用没有权限的路径时,就会报出这个错,比如:

rsync B/ /home/

如果你没有 /home 的写入权限,那上述命令就会报权限被拒绝(普通用户通常不这样做)。

2. 在<路径>中设置时间错误(rsync failed to set times on <path>)

当文件系统无法处理文件和目录的修改时间时,就会发生这种情况。关于这个问题,可以参考:

https://superuser.com/questions/200012/rsync-failed-to-set-times-on-dir-path

以上就是本次分享全部内容,欢迎讨论。

d85b1253d83ade9c05292248db0dc484.gif

往期推荐

40 张图 详解 Docker 容器监控

剖析 kubernetes 集群内部 DNS 解析原理

Docker 镜像和容器的导入导出及常用命令

实战 Kubectl 创建 Deployment 部署应用

dc2192c94d7c1385d79c57965b6ec4a3.gif

点分享

37c2610906dbabc2ac48dca2cac1b948.gif

点收藏

db44160ff84a06f2b94ebaf1b369c10d.gif

点点赞

a4d5d5eb9cdd2b710d237d2c438fc0a9.gif

点在看

;