调整Bash rsync脚本,解决FUSE文件系统视频复制不完整问题
解决rsync从FUSE文件系统复制视频文件不全的问题
核心问题排查
首先注意到你提供的脚本中,过滤规则匹配的都是音频格式(如MP3、FLAC等),但你的需求是复制视频文件——这是导致视频文件没被复制的直接原因之一。
其次,FUSE挂载的云存储(GDrive、Insync、Cryptomator)存在特殊属性:比如权限限制、文件元数据不完整、文件名编码差异,这些都会导致rsync的默认规则出现匹配异常。
修正后的脚本及调整说明
以下是针对你的需求优化后的脚本,适配FUSE文件系统并确保视频文件完整复制:
#!/bin/bash # 定义源目录和目标目录 src_dir="/home/user/cloud" dest_dir="/home/user/testmove" # rsync 参数说明: # -r: 递归遍历目录 # -h: 人类可读格式显示进度 # -P: 保留部分传输的文件 + 显示进度 # -v: verbose输出,便于排查 # --ignore-case: 忽略文件名大小写,无需写[mM][pP]4这种复杂规则 # --no-perms --no-owner --no-group: 跳过权限/所有者/组的同步,适配FUSE文件系统的权限限制 # --inplace: 直接在目标文件中写入,避免FUSE上的临时文件问题 # --prune-empty-dirs: 在目标目录中移除空目录 # --stats: 输出传输统计信息 rsync -rPvh \ --ignore-case \ --no-perms --no-owner --no-group \ --inplace \ --prune-empty-dirs \ --stats \ # 包含常见视频格式,根据你的需求补充或删减 -f'+ *.mp4' \ -f'+ *.mkv' \ -f'+ *.avi' \ -f'+ *.mov' \ -f'+ *.flv' \ -f'+ *.wmv' \ -f'+ *.webm' \ # 包含所有目录,确保递归遍历 -f'+ */' \ # 排除其他所有文件 -f'- *' \ "$src_dir"/ "$dest_dir" # 可选:如果需要清理源目录中的空目录 # find "$src_dir" -depth -type d -empty -delete
关键调整点说明
- 修正格式过滤规则:替换为视频格式(MP4、MKV等),并通过
--ignore-case参数简化大小写匹配,避免手动写[mM][pP]4这种繁琐规则。 - 适配FUSE文件系统:
- 移除
-a参数(归档模式),改用-r递归,因为FUSE文件系统通常不支持完整的POSIX权限/元数据,-a包含的权限同步会导致rsync误判文件状态。 - 添加
--no-perms --no-owner --no-group跳过权限相关同步,避免因FUSE权限问题导致文件被跳过。 - 添加
--inplace参数,解决FUSE文件系统上临时文件创建失败的问题。
- 移除
- 过滤规则的正确性:
- 确保规则顺序:先包含需要的文件格式,再包含所有目录(保证递归遍历),最后排除所有其他文件。
- 如果需要严格匹配文件名后缀(避免匹配类似
file.mp4.txt的文件),可以在规则末尾加上\$并转义,比如-f'+ *.mp4\$',或者用单引号包裹规则-f'+ *.mp4$'(单引号会阻止shell解析$符号)。
- 移除测试模式:原脚本中的
-n是干运行模式(只模拟操作不实际复制),实际执行时要删除该参数。
排查剩余问题的技巧
如果仍然存在部分视频文件未被复制,可以通过以下方式排查:
- 添加
--debug=filter,file参数,让rsync输出详细的过滤和文件匹配日志,查看哪些文件被跳过以及原因。 - 检查FUSE挂载目录的权限:确保当前用户对
$src_dir及其子目录有完整的读取权限,执行ls -la "$src_dir"确认。 - 检查特殊文件名:如果文件名包含空格、非ASCII字符(如中文、emoji),确保脚本中路径用双引号包裹(你的脚本已经做到),rsync默认支持这些字符,但可以添加
--iconv=utf-8,utf-8参数强制编码一致性。
内容的提问来源于stack exchange,提问作者saltyeggs
相关产品推荐
相关产品推荐

