类别: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_FILE

5. 设置脚本权限并测试

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,那用第二点是最优。

打赏

感谢您的赞助~

打开支付宝扫一扫,即可进行扫码打赏哦~

版权声明 : 本文未使用任何知识共享协议授权,您可以任何形式自由转载或使用。

 可能感兴趣的文章