在之前的文章中介绍过自动复制的脚本,使用 rsync + cifs-utils从Linux服务器上定时复制文件夹到Windows共享中,但是运行一段时间后发现,存在挂载残留风险、无错误检查以及中文乱码隐患,导致长期占据机器的资源。
今天借助AI的能力将脚本做了优化:
#!/bin/bash# ================= 配置区域 =================WIN_SHARE="//10.136.176.109/s"MOUNT_POINT="/mnt/windows_share"SOURCE_DIR="/home/resources/cms/"CIFS_USER="abcd"CIFS_PASS="密码1234"# 日志函数log() {echo"[$(date '+%F %T')] $1"}# ================= 开始执行 =================# 1. 检查源目录是否存在if [ ! -d "$SOURCE_DIR" ]; thenlog"错误: 源目录 $SOURCE_DIR 不存在,退出。"exit 1fi# 2. 确保挂载点目录存在if [ ! -d "$MOUNT_POINT" ]; thenlog"创建挂载点目录 $MOUNT_POINT" mkdir -p "$MOUNT_POINT"fi# 3. 智能挂载检查if mountpoint -q "$MOUNT_POINT"; thenlog"检测到 $MOUNT_POINT 已挂载,复用现有连接。"elselog"正在挂载 Windows 共享..."# 优化挂载参数:# noperm: 客户端不进行权限检查,完全信任服务器端(提高兼容性)# file_mode/dir_mode: 设置默认掩码,确保可写# iocharset=utf8: 防止中文文件名乱码if ! sudo mount -t cifs "$WIN_SHARE""$MOUNT_POINT" -o username="$CIFS_USER",password="$CIFS_PASS",iocharset=utf8,file_mode=0755,dir_mode=0755,noperm; thenlog"错误: 挂载失败!请检查网络、IP 或密码。"exit 1filog"挂载成功。"fi# 定义清理函数:脚本退出时自动执行cleanup() {log"正在执行清理卸载 (lazy unmount)..."# 使用 -l (lazy unmount) 是关键!# 即使 rsync 卡死或文件被占用,也能立即分离挂载点,防止僵尸挂载积累if sudo umount -l "$MOUNT_POINT" 2>/dev/null; thenlog"卸载完成。"elselog"警告: 卸载命令执行异常,但已尝试强制分离。"fi}# 注册退出陷阱:无论正常结束还是报错中断,都会执行 cleanuptrap cleanup EXIT# 4. 执行同步log"开始同步 CMS 资源..."# 【关键修正】# 1. 修正目标目录变量:原脚本用了不存在的 $DEST_DIR,已改为 $MOUNT_POINT# 2. 移除 --contimeout:该参数在普通 rsync 模式下无效,会报错# 3. 调整同步策略:# - 去掉 -a (archive),改用 -rlzD# - 增加 --no-t --no-p --no-o --no-g# 原因:Windows CIFS 不支持 Linux 的完整权限/时间属性,强行同步常导致 Error 13 或 23。# 我们只关注文件内容 (-r, -l, -z, -D) 的同步。if rsync -rlzD --timeout=60 --no-t --no-p --no-o --no-g "$SOURCE_DIR""$MOUNT_POINT"; thenlog"✅ 同步成功。"else code=$?if [ $code -eq 23 ]; thenlog"⚠️ 同步完成,但部分文件被跳过 (代码 23)。通常是文件名含非法字符,不影响主要数据。"elselog"❌ 警告: 同步过程中出现严重错误 (rsync 退出码: $code)。"fifilog"脚本执行结束。"# 此处自动触发 trap cleanup