小易说IT 小易说IT

mc(Midnight Commander)文件同步 shell 脚本示例

mc 自带 mcsync 工具,用于目录同步(本质是封装 mc 的文件同步逻辑,也可以直接调用 mc --shell 或者使用 mcsync;注意:mcsync 是 mc 配套的同步工具,不是独立二进制,部分精简系统需要单独安装 mc 包) 适用场景:本地 ↔ 本地、本地 ↔ sftp/ftp 远程目录同步(mc 内置虚拟文件系统 vfs)

前置依赖

# CentOS/RHEL
yum install mc -y
# Debian/Ubuntu
apt install mc -y

⚠️ 区分:mcsyncrsync。mcsync 优势是支持 mc 各类 VFS (sftp,ftp,tar 等);生产大量文件同步优先 rsync,mcsync 适合小批量、需要 mc 协议场景。

示例 1:mcsync 本地目录同步脚本(基础)

mcsync 语法:mcsync [选项] 源目录 目标目录

#!/bin/bash
# mc mcsync 目录同步脚本
# 同步源 -> 目标,增量同步,新建/更新文件,默认不删除目标多余文件

# 配置
SRC="/data/source_dir"
DST="/data/target_dir"
LOG_FILE="/var/log/mcsync_backup.log"

# 检查mc是否安装
if ! command -v mcsync &> /dev/null; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: mcsync not found, please install mc" | tee -a ${LOG_FILE}
    exit 1
fi

# 检查源目录
if [ ! -d "${SRC}" ];then
    echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: source dir ${SRC} not exists" | tee -a ${LOG_FILE}
    exit 1
fi

echo "=====================================" | tee -a ${LOG_FILE}
echo "$(date '+%Y-%m-%d %H:%M:%S') START sync ${SRC} ==> ${DST}" | tee -a ${LOG_FILE}

# mcsync 参数说明
# -u : update 只复制更新/新增文件
# -c : checksum 校验文件内容(默认是时间+大小)
# -P : 保留权限
# 不带 --delete:不会删除目标端多余文件
mcsync -u -P "${SRC}" "${DST}"

RET=$?
if [ ${RET} -eq 0 ];then
    echo "$(date '+%Y-%m-%d %H:%M:%S') SUCCESS sync finished" | tee -a ${LOG_FILE}
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR sync failed, code:${RET}" | tee -a ${LOG_FILE}
fi

exit ${RET}

示例 2:mcsync 本地同步 + 删除目标多余文件(镜像同步)

--delete 谨慎使用!会删除目标目录中源不存在的文件

#!/bin/bash
SRC="/data/source"
DST="/data/mirror_target"
LOG="/var/log/mcsync_mirror.log"

echo "$(date '+%Y-%m-%d %H:%M:%S') Mirror sync start" >> ${LOG}
# -u 更新,--delete 删除目标多余文件
mcsync -u --delete "${SRC}" "${DST}"
echo "$(date '+%Y-%m-%d %H:%M:%S') Mirror sync end" >> ${LOG}

示例 3:MC VFS + mcsync 本地同步到远程 SFTP(重点)

mc 支持 sftp VFS 路径格式:sftp://user@host/path/

前提:配置 ssh 免密登录,否则交互式输入密码会卡住脚本

#!/bin/bash
# 本地目录同步到远程 sftp 服务器
LOCAL_SRC="/data/local_files"
REMOTE_DST="sftp://root@192.168.1.100/backup/data"
LOG="/var/log/mcsync_sftp.log"

echo "$(date '+%Y-%m-%d %H:%M:%S') start sync local -> sftp" | tee -a ${LOG}
mcsync -u -P "${LOCAL_SRC}" "${REMOTE_DST}"
RET=$?
if [ ${RET} -eq 0 ];then
    echo "sync ok" | tee -a ${LOG}
else
    echo "sync error" | tee -a ${LOG}
fi

示例 4:调用 mc 交互式命令模式(mc --shell,不推荐自动化)

mc 还有 mc --shell 模式,可以执行 mc 内部命令,适合复杂 mc 操作,但自动化稳定性差,一般优先 mcsync

#!/bin/bash
# mc shell 模式示例(仅演示,不推荐生产同步)
mc --shell <<EOF
cd /data/src
mirror /data/dst
quit
EOF

mcsync 常用参数清单

-u, --update        只复制新文件或更新文件
-c, --checksum      使用文件校验和判断是否更新(慢,精准)
-P, --preserve      保留文件权限、属主、时间
--delete            删除目标目录源不存在的文件(镜像)
-n, --dry-run       试运行,只打印操作,不实际复制(强烈建议先测试)
-v, --verbose       详细输出日志

使用注意事项

  1. 先 dry-run 测试:上线同步脚本前,加 -n 参数试运行,确认文件列表是否符合预期

    mcsync -u -n --delete /src /dst
    
  2. 远程 SFTP 场景:必须 ssh 免密;mcsync 无法传入密码参数,密码方式只能交互式,无法 shell 自动化

  3. 性能对比:大量小文件 / 大文件,rsync 远优于 mcsync;mcsync 价值在于 mc 支持 ftp/sftp/zip/tar 等虚拟文件系统

  4. 权限:同步保留属主 -P 需要 root 权限

  5. 坑点:部分版本 mc,mcsync 不会递归符号链接,需要额外参数

增加定时任务 crontab

# 每天凌晨2点执行同步
0 2 * * * /opt/scripts/mcsync_backup.sh >> /var/log/mcsync_cron.log 2>&1

本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。

原文链接 https://www.yijunzhao.cc/archives/mc-file-sync-shell-script-example

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/