Linux服务器之间同步文件
1. 安装inotify-tools
该工具用于监测文件的变化
sudo apt-get install inotify-tools -y
2. 安装文件传输工具,这里有两种常见的工具
scp
- 一般linux系统会自带
rsync
- 安装指令
sudo apt-get install rsync
- 安装指令
如果只是需要复制少量的文件,使用scp
即可,但如果你需要复制大量的文件,特别是需要增量更新或错误恢复,那么最好使用 rsync
。
3. 编写脚本
创建一个名为watcher.sh
的shell脚本,并将以下代码复制粘贴到文件中:
scp
写法:
#!/bin/bash
# 监视的目录
watch_dir=/wadir/
# 目标服务器的SSH信息
remote_user=root
remote_host=114.514.191.981
remote_dir=/redir/
# 监视目录的变化并上传
inotifywait -m -r -e close_write,moved_to "$watch_dir" | while read path action file; do
# 检查文件是否为普通文件,且不是临时文件或备份文件
if [[ -f "$path$file" && ! $file =~ .*~$ && ! $file =~ ^\..*$ ]]; then
echo "$(date) 文件创建: $path$file"
# 尝试将文件上传到远程服务器
while true; do
scp -rv "$path$file" $remote_user@$remote_host:$remote_dir
if [[ $? -eq 0 ]]; then
echo "$(date) 文件上传成功: $path$file".
break
else
echo "$(date) 文件上传失败: $path$file"
sleep 10 # 等待10秒后再次上传
fi
done
fi
done
其中,
-r
参数表示以递归方式传输文件-v
参数表示详细模式输出
rsync
写法:
#!/bin/bash
# 监视的目录
watch_dir=/wadir/
# 目标服务器的SSH信息
remote_user=root
remote_host=114.514.191.981
remote_dir=/redir/
# 监视目录的变化并上传
inotifywait -m -r -e close_write,moved_to "$watch_dir" | while read path action file; do
# 检查文件是否为普通文件,且不是临时文件或备份文件
if [[ -f "$path$file" && ! $file =~ .*~$ && ! $file =~ ^\..*$ ]]; then
echo "$(date) 文件创建: $path$file"
# 尝试将文件上传到远程服务器
while true; do
rsync -avz --progress "$path$file" $remote_user@$remote_host:$remote_dir
if [[ $? -eq 0 ]]; then
echo "$(date) 文件同步成功: $path$file".
break
else
echo "$(date) 文件同步失败: $path$file"
sleep 10 # 等待10秒后再次尝试
fi
done
fi
done
其中,
-a
参数表示以递归方式传输文件,并保留文件属性-v
参数表示详细模式输出-z
参数表示进行压缩处理--progress
参数可以显示传输过程
4. 配置脚本
修改以下变量:
watch_dir
:你要监视的目录的路径(本地)remote_user
:目标服务器的用户名remote_host
:目标服务器的IP地址remote_dir
:要上传文件的目标目录路径 (远程)
赋予脚本权限:
chmod +x watcher.sh
最后在终端中运行脚本:
./watcher.sh
5.问题改进
上面的脚本有一个特点:每次传输文件都需要输入密码方能进行传输,解决方法是复制ssh公钥。
-
一种方法是在执行脚本前预先进行ssh密钥操作:
首先生成ssh密钥
ssh-keygen -t rsa -f ~/.ssh/id_rsa_new -q -N ""
生成成功后不会有任何提示,接着将生成的ssh公钥复制到远程服务器上
ssh-copy-id -i ~/.ssh/id_rsa_new.pub 服务器用户名@服务器IP
输入后会提示你输入远程服务器的密码,复制成功后如下图
随后执行脚本即可 -
另一种方法是修改脚本成这样(以rsync为例子),即在传输前加上
sshpass -p $remote_passwd
#!/bin/bash
sudo apt-get install sshpass -y
# 监视的目录
watch_dir=/wadir/
# 目标服务器的SSH信息
remote_user=root
remote_host=114.514.191.981
remote_dir=/redir/
remote_passwd=1145141919810
# 进行复制ssh公钥
ssh-keygen -t rsa -f ~/.ssh/id_rsa_new -q -N ""
sshpass -p $remote_passwd ssh-copy-id -i ~/.ssh/id_rsa_new.pub $remote_user@$remote_host
# 监视目录的变化并上传
inotifywait -m -r -e close_write,moved_to "$watch_dir" | while read path action file; do
# 检查文件是否为普通文件,且不是临时文件或备份文件
if [[ -f "$path$file" && ! $file =~ .*~$ && ! $file =~ ^\..*$ ]]; then
echo "$(date) 文件创建: $path$file"
# 尝试将文件上传到远程服务器
while true; do
sshpass -p $remote_passwd rsync -avz --progress "$path$file" $remote_user@$remote_host:$remote_dir
if [[ $? -eq 0 ]]; then
echo "$(date) 文件同步成功: $path$file".
break
else
echo "$(date) 文件同步失败: $path$file"
sleep 10 # 等待10秒后再次尝试
fi
done
fi
done