类别:CentOS / 日期:2025-12-18 / 浏览:13 / 评论:0
远程服务器A,系统是linux,已安装ftp服务,共享目录是/home/web,假如服务器IP:118.32.22.53,ftp用户名:ftpuser,ftp密码:ftp123456。已开启ssh,端口是:22
需求:将服务器A的/home/web按增量同步到本地服务器的/home/web_backup中,同步间隔是每天00:00开始。本地服务器系统是centos7。
方法一、利用FTP服务方式,使用 lftp 定时同步
1. 安装 lftp
yum install -y lftp
2、创建本地同步文件目录和脚本目录
mkdir -p /home/web_backup mkdir -p /home/scripts #日志目录 mkdir -p /home/logs
3. 创建同步脚本
vi /home/scripts/sync_ftp.sh
以下是脚本内容:
#!/bin/bash # FTP自动同步脚本 # FTP服务器配置 FTP_HOST="118.32.22.53" # FTP服务器地址 FTP_USER="ftpuser" # 用户名 FTP_PASS="ftp123456" # 密码 REMOTE_DIR="/home/web" # 远程目录 LOCAL_DIR="/home/web_backup" # 本地目录 # 执行同步 lftp -u $FTP_USER,$FTP_PASS $FTP_HOST << EOF set ftp:ssl-allow no # 禁用SSL(普通FTP) set mirror:use-pget-n 5 # 大文件分5段下载 set net:timeout 30 # 设置超时30秒 set net:max-retries 3 # 最大重试3次 mirror --delete --only-newer --verbose --parallel=5 "$REMOTE_DIR" "$LOCAL_DIR" bye EOF # 检查同步结果并记录日志 if [ $? -eq 0 ]; then echo "$(date): 同步成功完成" >> /home/logs/ftp_sync.log else echo "$(date): 同步失败,请检查网络或配置" >> /home/logs/ftp_sync.log fi
以下是核心命令解释:
mirror --delete --only-newer --verbose --parallel=5 "$REMOTE_DIR" "$LOCAL_DIR"
这是最关键的部分,执行目录镜像同步:
选项说明:
mirror:镜像命令,用于同步两个目录
--delete:删除本地多余文件。如果远程服务器上删除了某个文件,本地也会删除对应的文件,保持完全一致
--only-newer :只下载更新的文件,增量备份
--verbose:显示详细的操作信息,让你能看到正在同步哪些文件
--parallel=5:同时传输 5 个文件,加快同步速度
参数说明:
"$REMOTE_DIR":远程服务器上的源目录路径
"$LOCAL_DIR":本地目标目录路径
同步方向:从远程($REMOTE_DIR)同步到本地($LOCAL_DIR)
结束命令
bye
退出 lftp 会话
EOF:标记 Here Document 结束
其他有用的 mirror 选项:
| 选项 | 说明 | 使用场景 |
|---|---|---|
--only-newer | 只下载更新的文件 | 增量备份 |
--no-empty-dirs | 不创建空目录 | 精简同步 |
--exclude "*.tmp" | 排除特定文件 | 过滤不需要的文件 |
--dry-run | 模拟运行,不实际操作 | 测试同步效果 |
-R | 反向同步(上传到服务器) | 本地到远程的备份 |
3. 设置脚本权限
chmod +x /home/scripts/sync_ftp.sh
4. 设置 crontab 定时任务
crontab -e
添加以下内容:
# 每天00:01开始执行 1 0 * * * /home/scripts/sync_ftp.sh # 例如每5分钟同步一次(以下已注释了) # */5 * * * * /home/scripts/sync_ftp.sh
到此,已完成操作。
方法二、使用 rsync + SSH
1. 安装 rsync
# 在本地CentOS 7上安装rsync yum install -y rsync # 验证安装 rsync --version
2. 配置SSH密钥认证(免密码登录)
这是自动化的关键步骤:
# 1. 在本地服务器生成SSH密钥对(如果已有可跳过) ssh-keygen -t rsa -b 4096 -f ~/.ssh/remote_sync_key -N "" # 解释:本地生成密钥对(无需网络连接)。-N "" 表示密钥不设置密码短语(空密码)。生成两个文件:~/.ssh/remote_sync_key:私钥(保密!)~/.ssh/remote_sync_key.pub:公钥(可公开) # 查看生成的文件 ls -la ~/.ssh/my_sync_key* # 2. 将公钥复制到远程服务器 ssh-copy-id -i ~/.ssh/remote_sync_key.pub user@远程服务器IP # 这里需要远程服务器密码,但只有这一次! # 系统会提示:user@192.168.1.100's password: # 如果ssh-copy-id不可用,手动复制: cat ~/.ssh/remote_sync_key.pub | ssh user@远程服务器IP "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" # 设置正确的文件权限 chmod 700 ~/.ssh chmod 600 ~/.ssh/my_sync_key # 私钥:仅所有者可读 chmod 644 ~/.ssh/my_sync_key.pub # 公钥:可公开 chmod 644 ~/.ssh/authorized_keys # 远程服务器上的文件
3. 测试SSH连接
# 测试密钥登录是否正常 ssh -i ~/.ssh/remote_sync_key user@远程服务器IP "echo 'SSH连接成功'" # 如果配置正确,会直接登录,不再要求密码
4. 创建rsync同步脚本
vi /opt/scripts/ssh_sync.sh
脚本内容:
#!/bin/bash
# SSH远程同步脚本
# 配置参数
REMOTE_USER="用户名"
REMOTE_HOST="远程服务器IP"
REMOTE_PORT="22" # SSH端口,默认22
REMOTE_DIR="/远程/目录"
LOCAL_DIR="/本地/目录"
SSH_KEY="~/.ssh/remote_sync_key"
# 日志文件
LOG_FILE="/var/log/ssh_sync_$(date +%Y%m%d).log"
echo "=== 开始同步 $(date) ===" >> $LOG_FILE
# 使用rsync通过SSH同步
rsync -avz --delete \
-e "ssh -i $SSH_KEY -p $REMOTE_PORT -o StrictHostKeyChecking=no" \
--progress \
--exclude="*.tmp" \
--exclude="*.log" \
--exclude=".git/" \
$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ \
$LOCAL_DIR/ \
2>&1 | tee -a $LOG_FILE
# 检查同步结果
SYNC_STATUS=${PIPESTATUS[0]}
if [ $SYNC_STATUS -eq 0 ]; then
echo "同步成功完成 $(date)" >> $LOG_FILE
echo "同步的文件数量: $(find $LOCAL_DIR -type f | wc -l)" >> $LOG_FILE
else
echo "同步失败,错误代码: $SYNC_STATUS $(date)" >> $LOG_FILE
fi
echo "=== 同步结束 $(date) ===" >> $LOG_FILE5. 设置脚本权限并测试
chmod +x /opt/scripts/ssh_sync.sh # 手工测试 sh /opt/scripts/ssh_sync.sh
如何配置计划任务,请参考第一点
关键命令的解释:
命令: rsync -avz --delete \ -e "ssh -i $SSH_KEY -p $REMOTE_PORT -o StrictHostKeyChecking=no" \ --progress \ --exclude="*.tmp" \ --exclude="*.log" \ --exclude=".git/" \ $REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ \ $LOCAL_DIR/ \ 2>&1 | tee -a $LOG_FILE ---------解释------------------- 1. 基本同步选项 【rsync -avz --delete】 -a:归档模式(archive),相当于 -rlptgoD,包含以下: ( -r:递归复制目录 -l:复制符号链接 -p:保留权限 -t:保留修改时间 -g:保留属组 -o:保留属主 -D:保留设备文件) -v:详细输出(verbose),显示正在处理的文件 -z:传输时压缩数据,节省带宽 --delete:删除本地多余文件,使本地成为远程的精确镜像 2. SSH 连接配置 【-e "ssh -i $SSH_KEY -p $REMOTE_PORT -o StrictHostKeyChecking=no"】 -e:指定远程shell程序 ssh -i $SSH_KEY:使用指定的SSH私钥文件认证 -p $REMOTE_PORT:指定SSH端口(默认22) -o StrictHostKeyChecking=no:自动接受SSH主机密钥(重要!) 首次连接时不提示确认 避免自动化脚本因提示而中断 ⚠️ 安全注意:在生产环境中可能需要更严格的检查 3. 传输控制和过滤 【--progress --exclude="*.tmp" --exclude="*.log" --exclude=".git/"】 --progress:显示传输进度(百分比、速度等) --exclude="*.tmp":排除所有 .tmp 临时文件 --exclude="*.log":排除所有 .log 日志文件 --exclude=".git/":排除 Git 版本控制目录 4. 源和目标路径 【$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/ $LOCAL_DIR/】 源:用户@主机:远程目录/ 末尾的 / 很重要!表示复制目录内容,而不是目录本身 目标:本地目录/ 同步方向:从远程 → 本地 5. 日志处理 【2>&1 | tee -a $LOG_FILE】 2>&1:将标准错误(stderr)重定向到标准输出(stdout) |:管道符,将输出传递给下一个命令 tee -a $LOG_FILE: tee:同时输出到屏幕和文件 -a:追加模式(append),不覆盖原有日志 $LOG_FILE:日志文件路径
方法三、使用 scp 进行同步
scp 是基于 SSH 的文件传输工具,虽然功能不如 rsync 丰富,但简单直接,适合一次性传输或小规模同步。
1. 基础 SCP 同步脚本
vi /opt/scripts/scp_sync.sh
以下是脚本内容:
#!/bin/bash
# SCP 同步脚本
# 配置参数
REMOTE_USER="用户名"
REMOTE_HOST="远程服务器IP"
REMOTE_PORT="22"
REMOTE_DIR="/远程/目录"
LOCAL_DIR="/本地/目录"
SSH_KEY="~/.ssh/remote_sync_key"
# 日志文件
LOG_FILE="/var/log/scp_sync_$(date +%Y%m%d).log"
echo "=== SCP同步开始 $(date) ===" >> $LOG_FILE
# 1. 先确保本地目录存在
mkdir -p "$LOCAL_DIR"
# 2. 使用 scp 递归复制整个目录
scp -ri -P "$REMOTE_PORT" \
-o "IdentityFile=$SSH_KEY" \
-o "StrictHostKeyChecking=no" \
-o "ConnectTimeout=30" \
"$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" \
"$LOCAL_DIR/" \
2>&1 | tee -a $LOG_FILE
SCP_STATUS=${PIPESTATUS[0]}
if [ $SCP_STATUS -eq 0 ]; then
echo "SCP同步成功完成 $(date)" >> $LOG_FILE
echo "传输的文件数: $(find $LOCAL_DIR -type f | wc -l)" >> $LOG_FILE
else
echo "SCP同步失败,错误代码: $SCP_STATUS $(date)" >> $LOG_FILE
fi
echo "=== SCP同步结束 $(date) ===" >> $LOG_FILE如何配置脚本权限和计划等请参考第一点,如何配置SSH密钥认证(免密码登录)请参考第二点
2. 改进版:带增量检查的 SCP 脚本
纯 scp 不支持增量同步,但可以结合其他命令实现,以下是改进版脚本:
#!/bin/bash
# 带简单增量检查的 SCP 同步
REMOTE_USER="user"
REMOTE_HOST="remote.example.com"
REMOTE_DIR="/data/files"
LOCAL_DIR="/backup/files"
SSH_KEY="/root/.ssh/sync_key"
# 临时文件列表
REMOTE_LIST="/tmp/remote_files.txt"
LOCAL_LIST="/tmp/local_files.txt"
TO_SYNC_LIST="/tmp/files_to_sync.txt"
echo "开始SCP增量同步: $(date)"
# 1. 获取远程文件列表(带修改时间)
ssh -i "$SSH_KEY" "$REMOTE_USER@$REMOTE_HOST" \
"find '$REMOTE_DIR' -type f -printf '%p %T@\n'" > "$REMOTE_LIST"
# 2. 获取本地文件列表
find "$LOCAL_DIR" -type f -printf '%p %T@\n' > "$LOCAL_LIST"
# 3. 比较需要同步的文件(使用awk)
awk 'FNR==NR{local[$1]=$2; next}
!($1 in local) || local[$1] < $2 {print $1}' \
"$LOCAL_LIST" "$REMOTE_LIST" > "$TO_SYNC_LIST"
# 4. 统计并传输
FILE_COUNT=$(wc -l < "$TO_SYNC_LIST")
echo "需要同步 $FILE_COUNT 个文件"
if [ $FILE_COUNT -gt 0 ]; then
while IFS= read -r FILE; do
# 计算相对路径
REL_PATH="${FILE#$REMOTE_DIR}"
# 确保本地目录存在
LOCAL_FILE_DIR="$(dirname "$LOCAL_DIR$REL_PATH")"
mkdir -p "$LOCAL_FILE_DIR"
# 使用 scp 传输单个文件
echo "传输: $REL_PATH"
scp -i "$SSH_KEY" \
-o "StrictHostKeyChecking=no" \
"$REMOTE_USER@$REMOTE_HOST:$FILE" \
"$LOCAL_DIR$REL_PATH"
done < "$TO_SYNC_LIST"
fi
# 5. 清理临时文件
rm -f "$REMOTE_LIST" "$LOCAL_LIST" "$TO_SYNC_LIST"
echo "同步完成: $(date)"以上三种方法各有优缺点。scp功能最简单最弱,一般用来临时传输文件,但在不能安装软件下可以使用。生产环境一般采用第一、第二点。第一点针对远程服务器是windows系统的。如果远程和本地服务器都是linux,而且远程服务器没开通ftp,那用第二点是最优。
