Rsync(Remote Sync)是一个用于在本地和远程系统之间同步文件和目录的开源工具。它专注于高效、快速和智能的数据传输,具有一些独特的特性,使其成为广泛应用的文件同步和备份工具。
我们可以通过该命令将本地文件同步到服务器,同样也可以将服务器文件同步到本地!!如果想优雅地实现同步备份任务,单靠这一个工具是行不通的,将面临以下两个问题:
① 如何不输入密码就登陆服务器(每次传输文件都要输入密码的话太麻烦)
② 如何实现定期同步一次(运行一次 rsync 命令只能同步一次)
ssh 利用密钥对免密登陆和 cron 定期执行 rsync 命令能够很好地解决这些问题!!
1、利用SSH密钥对实现免密登陆
Secure Shell(SSH) 是由 IETF(The Internet Engineering Task Force) 制定的建立在应用层基础上的安全网络协议。它是专为远程登录会话(甚至可以用Windows远程登录Linux服务器进行文件互传)和其他网络服务提供安全性的协议,可有效弥补网络中的漏洞。
SSH密钥实现免密登录过程:客户端首先为自己创建一对密钥(公钥、私钥),将公钥上传到需要访问的服务器上。连接时,客户端软件向服务器发送密钥验证请求。服务器在用户主目录下查找对应的公钥,并与客户端发送的公钥进行比较。如果两者匹配,服务器使用公钥加密一个挑战(challenge),并将其发送给客户端。客户端接收到挑战后,使用本地的私钥进行解密,再将解密后的内容发送给服务器完成登录。
1.1、客户端生成密钥对
本机为Windows操作系统,配置了WSL(Windows Subsystem for Linux)。通过WSL,用户可以在 Windows 上安装和运行 Linux 发行版,而无需使用虚拟机或双重引导系统。WSL 的出现使得开发者能够在 Windows 环境中使用一些特定于 Linux 的工具和命令,同时还能享受 Windows 操作系统的其他功能。如何配置wsl请参考,配置了wsl,既可以同步wsl下的linux发行版数据,也可以同步windows系统中的数据!!Windows上配置完整Linux开发环境(一):通过WSL在Window上安装Linux发行版_wsl windows7-CSDN博客
ssh-keygen -t rsa # 生成密钥对(id_rsa id_rsa.pub)在用户目录的.ssh/目录
## 实例:
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:loWZzfPzrQvYaZ7QuFoIiMX5GnL5DEoc3ng7weFn3m0 root@iZ2ze7u36zcnb3ancwsuntZ
The key's randomart image is:
+---[RSA 3072]----+
| ... . |
| +oo * o |
|+ Bo + + o |
|.==*+ o o + |
|.+.** o S . . |
|. .oo. = E . . |
| . . . + * . |
| o . |
| o . |
+----[SHA256]-----+
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# cd .ssh/ && ls
id_rsa id_rsa.pub
1.2、上传公钥到服务器
ssh-copy-id ursername@host # 上传公钥到服务器
## 实例
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:/etc/ssh# ssh-copy-id root@121.47.65.135
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '121.47.65.135(121.47.65.135)' can't be established.
ED25519 key fingerprint is SHA256:HsZRl0n3Emvt5SqZFHMH26aKlnpIstfyHvC0ZnbpcKs.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@121.47.65.135's password:Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@121.47.65.135'"
and check to make sure that only the key(s) you wanted were added.
1.3、通过ssh密钥免密登陆
ssh username@host # 现在就可以直接通过ssh免密登陆
## 实例
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:/etc/ssh# ssh 'root@121.47.65.135'
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-71-generic x86_64)* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantageSystem information as of Mon Feb 12 12:38:26 PM CST 2024
System load: 0.10791015625 Processes: 151
Usage of /: 26.7% of 39.01GB Users logged in: 1
Memory usage: 24% IPv4 address for eth0: 172.17.234.90
Swap usage: 0%* Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
just raised the bar for easy, resilient and secure K8s cluster deployment.https://ubuntu.com/engage/secure-kubernetes-at-the-edge
Expanded Security Maintenance for Applications is not enabled.
80 updates can be applied immediately.
To see these additional updates run: apt list --upgradable2 additional security updates can be applied with ESM Apps.
Learn more about enabling ESM Apps service at https://ubuntu.com/esm
*** System restart required ***Welcome to Alibaba Cloud Elastic Compute Service !
Last login: Mon Feb 12 12:22:50 2024 from 47.96.60.214
2、rsync 实现路径及文件的同步
rsync(Remote Sync)是一个强大的开源工具,用于在本地系统和远程系统之间同步文件和目录。它被广泛用于备份和镜像操作,可以通过SSH等安全协议进行远程同步。
2.1、常见用法
# 1. 从本地系统复制文件到远程系统:
rsync -avz /local/path/ user@remote:/remote/path/# 2. 从远程系统复制文件到本地系统:
rsync -avz user@remote:/remote/path/ /local/path/# 3. 从本地系统复制文件到远程系统并显示详细信息:
rsync -avz --verbose /local/path/ user@remote:/remote/path/# 4. 仅复制更新过的文件:
rsync -avzu /local/path/ user@remote:/remote/path/# 5. 同步两个目录,并删除目标目录中不存在的文件:
rsync -av --delete /source/dir/ /destination/dir/# 6. 显示同步进程
rsync -av -P /source/dir/ /destination/dir/
rsync -av --progress /source/dir/ /destination/dir/
# 7. 使用 ssh 登陆服务器 rsync 同步文件:
# 本地密钥登陆服务器同步文件到服务器
rsync -avz -e "ssh -i /path/to/private/key" /local/path/ user@remote:/remote/path/
# 本地密钥登陆服务器同步文件到本地
rsync -avz -e "ssh -i /path/to/private/key" user@remote:/remote/path/ /local/path/
# 8. 继续传输传到一半的文件(适用于某些较大文件传输时中断)
rsync --partial --append-verify /path/to/private/key" /local/path/ user@remote:/remote/path/
# 9. 模拟同步过程,显示会被复制、删除或更新的文件
rsync -avz --dry-run /path/to/private/key" /local/path/ user@remote:/remote/path/
# 10. 最小化输出
--info=progress2:只显示进度和一些基本信息
# 11. 禁用输出
--quiet或-q:完全禁用输出
详细用法见博客Rsync部分:Shell 编程-CSDN博客
2.2、生成测试文件夹
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# mkdir test
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# cd test
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~/test# touch {1..6}.txt
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~/test# mkdir infolder
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~/test# cd infolder/
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~/test/infolder# touch {a..e}.txt## 生成如下文件树
/root/test
├── 1.txt
├── 2.txt
├── 3.txt
├── 4.txt
├── 5.txt
├── 6.txt
└── infolder
├── a.txt
├── b.txt
├── c.txt
├── d.txt
└── e.txt
2.3、同步测试文件路径到服务器
# 本地密钥登陆服务器同步文件到服务器
rsync -avz -e "ssh -i /path/to/private/key" /local/path/ user@remote:/remote/path/
## 实例
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# rsync -avz -e "ssh -i /root/.ssh/id_rsa" /root/test/ root@121.47.65.135:/root/test
sending incremental file list
created directory /root/test
./
1.txt
2.txt
3.txt
4.txt
5.txt
6.txt
infolder/
infolder/a.txt
infolder/b.txt
infolder/c.txt
infolder/d.txt
infolder/e.txtsent 710 bytes received 269 bytes 652.67 bytes/sec
total size is 0 speedup is 0.00## 可以看到传输了/test/目录下的所有文件,包括子文件夹文件到服务器
注意: rysnc -avz是增量更新
再运行同步命令时,只会更新修改过的文件或添加的新文件,而不会删除本地已经删除了文件,如果想让本地和服务器文件完全相同,需添加--delete选项,即rsync -avz --delete。
以下是举例:
① 当前本地和服务器文件树如下,所有文件没有任何内容:
## 本地
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# tree ./test
./test
├── 1.txt
├── 2.txt
├── 3.txt
├── 4.txt
├── 5.txt
├── 6.txt
└── infolder
├── a.txt
├── b.txt
├── c.txt
├── d.txt
└── e.txt1 directory, 11 files
## 服务器
(base) root@iZ2ze7u36zcnb3ancwsuntZ:~# tree ./test/
./test/
├── 1.txt
├── 2.txt
├── 3.txt
├── 4.txt
├── 5.txt
├── 6.txt
└── infolder
├── a.txt
├── b.txt
├── c.txt
├── d.txt
└── e.txt1 directory, 11 files
② 本地文件写入内容,删除文件,添加文件
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# echo "This is a demo" > ./test/1.txt
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# rm ./test/2.txt
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# touch ./test/7.txt③ 采用增量更新 rsync -avz
rsync -avz -e "ssh -i /path/to/private/key" /local/path/ user@remote:/remote/path/
## 本地:修改1.txt,删除2.txt,增加7.txt
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# rsync -avz -e "ssh -i /root/.ssh/id_rsa" /root/test/ root@121.47.65.135:/root/test
sending incremental file list
./
1.txt
7.txtsent 411 bytes received 64 bytes 316.67 bytes/sec
total size is 15 speedup is 0.03# 可以看到只修改了服务器端的1.txt和7.txt,并没有删除服务器的2.txt文件,而本地2.txt已被删除,可以查看服务器端文件输
## 服务器文件树如下:
(base) root@iZ2ze7u36zcnb3ancwsuntZ:~# tree ./test/
./test/
├── 1.txt
├── 2.txt
├── 3.txt
├── 4.txt
├── 5.txt
├── 6.txt
├── 7.txt
└── infolder
├── a.txt
├── b.txt
├── c.txt
├── d.txt
└── e.txt1 directory, 12 files
④ 本地文件与服务器完全相同 rsync -avz --delete
(base) root@iZ0jl1ej1cvd2d9u63wtntZ:~# rsync -avz --delete -e "ssh -i /root/.ssh/id_rsa" /root/test/ root@121.47.65.135:/root/test
sending incremental file list
deleting 2.txtsent 310 bytes received 22 bytes 664.00 bytes/sec
total size is 15 speedup is 0.05# 可以看到,删除服务器端上一步本地删除的2.txt文件
⑤ 显示详细进度 rsync -avz -P
/root/test/1.txt
3,460 100% 3.21MB/s 0:00:01 (xfr#3, ir-chk=2/12)
3、利用 cron 实现定期执行 rsync 命令
一切都很完美,但如果每次都要手动执行 rsync命令未免太麻烦。
Cron(Command Run On)是一个用于在Unix和类Unix操作系统上定期执行任务的时间管理工具。它允许用户根据预定的时间间隔(例如每分钟、每小时、每天等)自动执行特定的命令或脚本。
Cron 使用一个称为 crontab 的配置文件来存储任务列表。每个用户都可以有自己的 crontab 文件,其中包含一系列计划执行的任务。管理员通常可以编辑系统范围的 crontab 文件,影响所有用户。
cron用法以及更多Linux操作命令详见:Shell 编程-CSDN博客
## cron用法
crontab -e # 编辑当前用户的 cron 表
# cron 表格式# m h dom mon dow command
# 分钟 (minute): 表示一小时中的哪一分钟执行任务,范围是 0 到 59。
# 小时 (hour): 表示一天中的哪一小时,范围是 0 到 23。
# 日 (dom, day of month): 表示一个月中的哪一天,范围是 1 到 31。
# 月 (month): 表示一年中的哪一个月,范围是 1 到 12。
# 星期几 (dow, day of week): 表示一周中的哪一天,范围是 0(星期日)到 6(星期六)。
在Cron表达式中,每个字段都可以使用数字或者通配符
*
。通配符*
表示“任意值”,因此* * * * *
表示每分钟都执行任务。## 示例
# 示例1 每周一的凌晨5点执行命令
0 5 * * 1 tar -zcf /var/backups/home.tgz /home/# 示例2 每分钟同步一下文件到服务器(-a增量更新,--delete删除不同)
* * * * * rsync -avz --delete -e "ssh -i /path/private/key" /local/path/ user@remote:/remote/path/
## 示例3 每天的7点到22点之间,每5分钟
*/5 7-22 * * *
# 编辑定期计划执行的任务,第一次执行会让用户选择哪种文件编辑器
crontab -e
# 在文件中添加,每分钟同步一次
*/1 * * * * rsync -av --delete -e "ssh -i /root/.ssh/id_rsa" /root/test/ root@121.47.65.135:/root/test/
# 编辑好后记得启动Cron服务,要不然不会运行
sudo service cron status
sudo service cron start
如此就实现了文件定期自动同步
4、思维延展
如果想像网盘一样从移动端访问文件夹,可以通过在服务器部署 Apache HTTP Server 的目录索引样式 mod_autoindex,以向外界提供文件夹浏览和下载服务。
可参考:如何实现访问apache时的目录浏览功能(apache file list view)_mod_autoindex-CSDN博客